Vorwort : Ich suche eine Erklärung, nicht nur eine Lösung. Ich kenne die Lösung bereits.
Obwohl ich mehrere Tage damit verbracht habe, MSDN-Artikel über das aufgabenbasierte asynchrone Muster (TAP) zu studieren, asynchron zu sein und zu warten, bin ich immer noch etwas verwirrt über einige der feineren Details.
Ich schreibe einen Logger für Windows Store Apps und möchte sowohl die asynchrone als auch die synchrone Protokollierung unterstützen. Die asynchronen Methoden folgen dem TAP, die synchronen sollten all dies verbergen und wie normale Methoden aussehen und funktionieren.
Dies ist die Kernmethode der asynchronen Protokollierung:
private async Task WriteToLogAsync(string text)
{
StorageFolder folder = ApplicationData.Current.LocalFolder;
StorageFile file = await folder.CreateFileAsync("log.log",
CreationCollisionOption.OpenIfExists);
await FileIO.AppendTextAsync(file, text,
Windows.Storage.Streams.UnicodeEncoding.Utf8);
}
Nun die entsprechende synchrone Methode ...
Version 1 :
private void WriteToLog(string text)
{
Task task = WriteToLogAsync(text);
task.Wait();
}
Das sieht richtig aus, funktioniert aber nicht. Das ganze Programm friert für immer ein.
Version 2 :
Hmm .. Vielleicht wurde die Aufgabe nicht gestartet?
private void WriteToLog(string text)
{
Task task = WriteToLogAsync(text);
task.Start();
task.Wait();
}
Das wirft InvalidOperationException: Start may not be called on a promise-style task.
Version 3:
Hmm .. Task.RunSynchronously
klingt vielversprechend.
private void WriteToLog(string text)
{
Task task = WriteToLogAsync(text);
task.RunSynchronously();
}
Das wirft InvalidOperationException: RunSynchronously may not be called on a task not bound to a delegate, such as the task returned from an asynchronous method.
Version 4 (die Lösung):
private void WriteToLog(string text)
{
var task = Task.Run(async () => { await WriteToLogAsync(text); });
task.Wait();
}
Das funktioniert. 2 und 3 sind also die falschen Werkzeuge. Aber 1? Was ist los mit 1 und was ist der Unterschied zu 4? Was bringt 1 zum Einfrieren? Gibt es ein Problem mit dem Aufgabenobjekt? Gibt es einen nicht offensichtlichen Stillstand?