C# 任务。运行冻结
有人能告诉我为什么在完成lambda后以下情况会冻结: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
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
应该没有必要)。如果你发代码,我会看一看。