Préface : Je cherche une explication, pas seulement une solution. Je connais déjà la solution.
Malgré avoir passé plusieurs jours à étudier des articles MSDN sur le modèle asynchrone basé sur les tâches (TAP), asynchroniser et attendre, je suis toujours un peu confus au sujet de certains des détails les plus fins.
J'écris un enregistreur pour les applications du Windows Store et je souhaite prendre en charge la journalisation asynchrone et synchrone. Les méthodes asynchrones suivent le TAP, les méthodes synchrones doivent masquer tout cela et ressembler et fonctionner comme des méthodes ordinaires.
Il s'agit de la méthode principale de la journalisation asynchrone:
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);
}
Maintenant, la méthode synchrone correspondante ...
Version 1 :
private void WriteToLog(string text)
{
Task task = WriteToLogAsync(text);
task.Wait();
}
Cela semble correct, mais cela ne fonctionne pas. L'ensemble du programme se bloque pour toujours.
Version 2 :
Hmm .. Peut-être que la tâche n'a pas commencé?
private void WriteToLog(string text)
{
Task task = WriteToLogAsync(text);
task.Start();
task.Wait();
}
Cela jette InvalidOperationException: Start may not be called on a promise-style task.
Version 3:
Hmm .. Task.RunSynchronously
semble prometteur.
private void WriteToLog(string text)
{
Task task = WriteToLogAsync(text);
task.RunSynchronously();
}
Cela jette 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 (la solution):
private void WriteToLog(string text)
{
var task = Task.Run(async () => { await WriteToLogAsync(text); });
task.Wait();
}
Cela marche. Donc, 2 et 3 ne sont pas les bons outils. Mais 1? Quel est le problème avec 1 et quelle est la différence avec 4? Qu'est-ce qui fait que 1 cause un gel? Y a-t-il un problème avec l'objet de tâche? Y a-t-il un blocage non évident?