标签:启动 没有 出现 something code service wpf 中断 mic
避免使用Task.Result和Task.Wait
只有极少方法可以正确的使用Task.Result和Task.Wait,一般情况下建议是完全避免在代码上出现。
同步异步
这里说的同步异步是指把异步操作通过Task.Result或Task.Wait阻塞线程转为同步,使用Task.Result和Task.Wait阻塞等待异步操作比起真正调用同步操作的API要糟糕的多,下面是经常发生的情况。
结果就是使用了2个线程来完成了只需要1个线程即可完成的同步操作,这往往会导致线程池饥饿最终导致服务中断。
死锁
在ASP.NET (Web Forms)、Windows Forms、WPF、UWP的UI线程上如果使用Task.Result和Task.Wait都会导致死锁。因为这些程序的UI都是单线程的,这些程序会在构造函数里会把UI线程的Task的同步上下文设置为SynchronizationContext的实例。如果UI线程出现阻塞,Task会在完成任务时候把等待UI线程Task的SynchronizationContext实例用来同步上下文,但UI线程又在等待Task完成,结果就导致死锁。由于这个原因,“聪明”的开发者想出了各种办法试图阻塞线程得到结果。事实上,阻塞异步任务并没有什么好方法。
注意:ASP.NET Core 并没有SynchronizationContext,所以并不容易出现死锁问题。
有时候开发人员会编写的一些"巧妙"的代码去试图避免死锁去同步异步
1 public string DoOperationBlocking() 2 { 3 return Task.Run(() => DoAsyncOperation()).Result; 4 } 5 6 public string DoOperationBlocking2() 7 { 8 return Task.Run(() => DoAsyncOperation()).GetAwaiter().GetResult(); 9 } 10 11 public string DoOperationBlocking3() 12 { 13 return Task.Run(() => DoAsyncOperation().Result).Result; 14 } 15 16 public string DoOperationBlocking4() 17 { 18 return Task.Run(() => DoAsyncOperation().GetAwaiter().GetResult()).GetAwaiter().GetResult(); 19 } 20 21 public string DoOperationBlocking5() 22 { 23 return DoAsyncOperation().Result; 24 } 25 26 public string DoOperationBlocking6() 27 { 28 return DoAsyncOperation().GetAwaiter().GetResult(); 29 } 30 31 public string DoOperationBlocking7() 32 { 33 var task = DoAsyncOperation(); 34 task.Wait(); 35 return task.GetAwaiter().GetResult(); 36 }
使用await取代Task.ContinueWith
在引入async / await 之前 Task已经存在了不依赖于语言关键字的函数 Task.ContinueWith 就是其中一个,虽然这些方法仍然可以使用,但我通常还是建议你使用 await 而不是Task.ContinueWith,事实上,Task.ContinueWith 和 await 并不是语法上不一样而已,Task.ContinueWith 不会保存任何类型的状态( ExecutionContext / SynchronizationContext ),如果没有提供回调,则默认会回到原来的线程上继续下接下来的操作。await 关键字则会在Task完成的时候保存状态到当前的线程然后再继续接下来的操作。
这个案例使用的是 Task.ContinueWith 而不是 await
1 public Task<int> DoSomethingAsync() 2 { 3 return CallDependencyAsync().ContinueWith(task => 4 { 5 return task.Result + 1; 6 }); 7 }
这个案例使用关键字 await 获取异步结果
1 public async Task<int> DoSomethingAsync() 2 { 3 var result = await CallDependencyAsync(); 4 return result + 1; 5 }
标签:启动 没有 出现 something code service wpf 中断 mic
原文地址:https://www.cnblogs.com/zigit/p/9939858.html