同步执行异步功能

Dev*_*Dev -2 c# asynchronous winforms async-await .net-4.5

我已经对这个主题进行了大量的搜索,我在这个网站上阅读了关于这个主题的大部分帖子,但是我仍然感到困惑,我需要一个直接的答案.这是我的情况:

我有一个已建立的Winform应用程序,我无法将其全部"异步".我现在被迫使用一个全部写为异步函数的外部库.

在我的申请中,我有

/// <summary>
/// This function I can't change it to an 'async'
/// </summary>
public void MySyncFunction()
{
    //This function is my point in my application where I have to call the
    //other 'async' functions but I can't change the function itself to 'async'

    try
    {
        //I need to call the MyAsyncDriverFunction() as if it is a synchronous function
        //I need the driver function to finish execution and return before processing the code that follows it
        //I also need to be able to catch any exceptions
        MyAsyncDriverFunction(); 

        //Rest of the code have to wait for the above function to return
    }
    catch (Exception exp)
    {
        //Need to be able to handle the exception thrown 
        //from the MyAsyncDriverFunction here.  
    }
}

public static async Task<IEnumerable<string>> MyAsyncDriverFunction()
{
    try
    {
        var strCollection = await AsyncExternalLibraryFunction1();
        var strCollection2 = await AsyncExternalLibraryFunction2();

        return strCollection;
    }
    catch (Exception exp)
    {
        //Need to be able to catch an exception and re-throw it to the caller function
    }
}
Run Code Online (Sandbox Code Playgroud)

如代码中所述,我需要能够:

  • 我无法将MySyncFunction更改为异步
  • 以同步方式调用"MyAsyncDriverFunction",在处理后面的代码之前,必须等待它完成所有工作
  • 能够处理两个函数中的异常(从我到目前为止读到的这个很棘手吗?)
  • 我需要一个使用标准API的简单方法,我不能使用任何第三方库(即使我想)

Ste*_*ary 5

但我仍然感到困惑,我需要一个直接的答案.

那是因为没有"直截了当"的答案.

唯一正确的解决方案是MySyncFunction异步的.期.所有其他解决方案都是黑客攻击,并且没有任何黑客在所有场景中都能完美运行.

我在最近的关于棕色字段异步开发的MSDN文章中详细介绍了,但这里有一个要点:

你可以用Wait()或阻止Result.正如其他人所指出的那样,您很容易导致死锁,但如果异步代码永远不会在其捕获的上下文中恢复,则可以使用此方法.

您可以将工作推送到线程池线程,然后阻止.但是,这假设异步工作能够被推送到其他任意线程,并且它可以在其他线程上恢复,因此可能引入多线程.

您可以将工作推送到执行"主循环"的线程池线程 - 例如,调度程序或我自己的AsyncContext类型.这假设异步工作能够被推送到另一个线程,但消除了对多线程的任何担忧.

您可以在主线程上安装嵌套的消息循环.这将在调用线程上执行异步代码,但也会引入重入,这是非常难以正确推理的.

简而言之,没有一个答案.每种方法都适用于不同类型的异步代码.