閱讀Stephen Toub's article on SynchronizationContext我留下了一個關於這一塊的.NET 4.5代碼的輸出問題後:的SynchronizationContext上Task.Run流而不是在等待
private void btnDoSomething_Click()
{
LogSyncContext("btnDoSomething_Click");
DoItAsync().Wait();
}
private async Task DoItAsync()
{
LogSyncContext("DoItAsync");
await PerformServiceCall().ConfigureAwait(false); //to avoid deadlocking
}
private async Task PerformServiceCall()
{
LogSyncContext("PerformServiceCall 1");
HttpResponseMessage message = await new HttpClient
{
BaseAddress = new Uri("http://my-service")
}
.GetAsync("/").ConfigureAwait(false); //to avoid deadlocking
LogSyncContext("PerformServiceCall 2");
await ProcessMessage(message);
LogSyncContext("PerformServiceCall 3");
}
private async Task ProcessMessage(HttpResponseMessage message)
{
LogSyncContext("ProcessMessage");
string data = await message.Content.ReadAsStringAsync();
//do something with data
}
private static void LogSyncContext(string statementId)
{
Trace.WriteLine(String.Format("{0} {1}", statementId, SynchronizationContext.Current != null ? SynchronizationContext.Current.GetType().Name : TaskScheduler.Current.GetType().Name));
}
輸出是:
btnDoSomething_Click WindowsFormsSynchronizationContext
DoItAsync WindowsFormsSynchronizationContext
PerformServiceCall 1 WindowsFormsSynchronizationContext
PerformServiceCall 2 ThreadPoolTaskScheduler
ProcessMessage的ThreadPoolTaskScheduler
PerformServiceCall 3 ThreadPoolTaskScheduler
但我希望PerformServiceCall 1至不能上WindowsFormsSynchronizationContext自文章指出,「的SynchronizationContext。目前沒有「流過」等待點「...
上下文與Task.Run和異步調用拉姆達時PerformServiceCall沒有獲得通過,像這樣:
await Task.Run(async() =>
{
await PerformServiceCall();
}).ConfigureAwait(false);
任何人都可以澄清或者點一些這方面的資料?
直到Task實際開始等待,ConfigureAwait()調用纔會有任何影響。那還沒有發生,你的LogSyncContext()調用要早。在等待之後移動它。 – 2015-04-01 09:48:06
是不是'DoItAsync()等待();'? – 2015-04-01 10:40:41
不,它不會由於ConfigureAwait調用而發生死鎖 – Stif 2015-04-02 13:27:36