Lor*_*ori 0 c# multithreading async-await
有什么区别:
public class Worker
{
public static void Execute()
{
ExecuteInBackgroundThread().Wait();
}
private static Task ExecuteInBackgroundThread()
{
return Task.Run(() =>
{
// do some long running operation
});
}
}
Run Code Online (Sandbox Code Playgroud)
和
public class Worker
{
public static void Execute()
{
ExecuteInBackgroundThread().Wait();
}
private static async Task ExecuteInBackgroundThread()
{
await Task.Run(() =>
{
// do some long running operation
});
}
}
Run Code Online (Sandbox Code Playgroud)
我注意到Worker.Execute()
从UI线程调用我的Windows Phone应用程序的第二个版本被卡住了.
相反,使用第一个版本似乎一切正常.
ExecuteInBackgroundThread
实际返回的第二个版本是否Task<T>
可以等待?但如果情况并非如此,编译器是否应该提出错误说我们没有返回任何内容?
首先,你的应用程序卡住的真正原因是你有一个僵局.那是因为你正在使用Task.Wait
哪个阻塞正在等待UI线程完成的任务的UI线程.
发生这种情况是因为只有一个UI线程,因此SynchronizationContext
只有使用该特定线程.
你可以通过使用来修复你的死锁ConfigureAwait(false)
,它不使用SynchronizationContext
:
private static async Task<T> ExecuteInBackgroundThread<T>()
{
await Task.Run(() =>
{
// do some long running operation
}).ConfigureAwait(false);
}
Run Code Online (Sandbox Code Playgroud)
除此之外,两个选项几乎相同,只要没有更多的代码在ExecuteInBackgroundThread
调用之外Task.Run
.第一个选项稍快,因为您直接使用Task.Run中的任务.第二个选项在顶部添加另一个冗余异步层(包括状态机等).
结论:您应该使用第一个选项.但是不要使用Wait
不仅会阻塞你的线程,但在某些情况下可能会导致死锁.