Nach Stephen Toub's article on SynchronizationContext Lesen ich mit einer Frage nach links über den Ausgang dieses Stück 4.5 Code .NET:SynchronizationContext fließt auf Task.Run aber nicht erwarten auf
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));
}
Die Ausgabe lautet:
btnDoSomething_Click WindowsFormsSynchronizationContext
DoItAsync WindowsFormsSynchronizationContext
PerformServiceCall 1 WindowsFormsSynchronizationContext
PerformServiceCall 2 ThreadPoolTaskScheduler
Process ThreadPoolTaskScheduler
PerformServiceCall 3 ThreadPoolTaskScheduler
Aber ich würde erwarten PerformServiceCall 1 nicht auf dem WindowsFormsSynchronizationContext zu sein, da der Artikel besagt, dass „SynchronizationContext. Der Strom fließt nicht über die Wartepunkte "...
Der Kontext nicht bestanden wird erhalten, wenn PerformServiceCall mit Task.Run und einem Asynchron-lambda, wie dies Aufruf:
await Task.Run(async() =>
{
await PerformServiceCall();
}).ConfigureAwait(false);
auf dem bis zu einem gewissen Dokumentation Kann jemand klären oder Punkt?
Der ConfigureAwait() - Aufruf hat keine Auswirkungen, bis der Task tatsächlich zu warten beginnt. Das ist noch nicht geschehen, Ihr LogSyncContext() - Aufruf war zu früh. Verschiebe es nach dem Warten. –
Ist das nicht Deadlock auf 'DoItAsync(). Wait();'? –
Nein, es ist kein Deadlock dank des ConfigureAwait-Aufrufs – Stif