C# 任务。运行冻结

C# 任务。运行冻结,c#,task-parallel-library,.net-4.5,async-await,c#-5.0,C#,Task Parallel Library,.net 4.5,Async Await,C# 5.0,有人能告诉我为什么在完成lambda后以下情况会冻结: return await Task.Run(() => { return SuperLongMethod(); }) …但以下工作仍如预期: return Task.Run(() => { return SuperLongMethod(); }).GetAwaiter().GetRes

有人能告诉我为什么在完成lambda后以下情况会冻结:

        return await Task.Run(() =>
        {
            return SuperLongMethod();
        })
…但以下工作仍如预期:

        return Task.Run(() =>
        {
            return SuperLongMethod();
        }).GetAwaiter().GetResult();
在第一个版本中运行的Task.Run似乎没有识别出lambda已经完成。我的代码中还有其他例子,我使用的第一个版本没有问题,所以我不知道区别是什么


为清楚起见,SuperLongMethod()进行web服务调用,并对结果数据进行大量后处理

我猜,您正在调用调用调用堆栈的
Task.Wait
Task.Result
,从而导致。您应该使用
wait


作为旁注,
超长方法
可能应分为
CallWebServiceAsync
DoPostProcessing
,而且只有
DoPostProcessing
应该被包装在
任务中。运行

我猜您正在调用调用调用堆栈的
任务。等待
任务。结果
,从而导致。您应该使用
wait


作为旁注,
SuperLongMethod
可能应该被分解成
CallWebServiceAsync
DoPostProcessing
,并且只有
DoPostProcessing
应该被包装在
任务中。Run

你的博客基本上说不要等待任务,这是一个解决这个令人困惑的死锁的方法,但我使用Task.Run的原因是为了有效地将处理强制到另一个线程上,以便GUI保持流畅。否则,当后期处理开始时,它就会受到打击。但是,您的博客建议在任务上使用ConfigureAwait(false)。Run工作得很好:)我还应该补充,我的第二个示例代码块实际上是阻塞的,所以这不是我认为的解决方法,实际上,我的博客帖子建议等待任务;它不鼓励阻塞任务。
ConfigureAwait
工作的事实向我表明,您的代码仍然不正确-在调用堆栈上,您仍然阻止从该
async
方法返回的任务。我的GUI直接使用await调用我的异步函数。在我的函数中,Task.Run执行并阻塞,但GUI保持响应。当Task.Run完成时,由于您建议的ConfigureAwait(false),它会继续运行,而在没有它之前,它会死锁。我不认为这种方法是错误的,除非您觉得可能存在不一致性。我仍然没有清楚地了解您的代码,但确实感觉有问题(
ConfigureAwait
应该没有必要)。如果你发布了你的代码,我会看一看。你的博客基本上是说不要等待任务,这是解决这个令人困惑的死锁的方法,但我使用Task.Run的原因是为了有效地将处理强制到另一个线程上,以便GUI保持流畅。否则,当后期处理开始时,它就会受到打击。但是,您的博客建议在任务上使用ConfigureAwait(false)。Run工作得很好:)我还应该补充,我的第二个示例代码块实际上是阻塞的,所以这不是我认为的解决方法,实际上,我的博客帖子建议等待任务;它不鼓励阻塞任务。
ConfigureAwait
工作的事实向我表明,您的代码仍然不正确-在调用堆栈上,您仍然阻止从该
async
方法返回的任务。我的GUI直接使用await调用我的异步函数。在我的函数中,Task.Run执行并阻塞,但GUI保持响应。当Task.Run完成时,由于您建议的ConfigureAwait(false),它会继续运行,而在没有它之前,它会死锁。我不认为这种方法是错误的,除非您觉得可能存在不一致性。我仍然没有清楚地了解您的代码,但确实感觉有问题(
ConfigureAwait
应该没有必要)。如果你发代码,我会看一看。