Préface : Je cherche une explication, pas seulement une solution. Je connais déjà la solution.
Bien que j'aie passé plusieurs jours à étudier les articles de MSDN sur le modèle asynchrone basé sur les tâches (TAP), async et await, je suis encore un peu perdu sur certains détails plus fins.
J'écris un enregistreur pour Windows Store Apps, et je veux prendre en charge l'enregistrement asynchrone et synchrone. Les méthodes asynchrones suivent le TAP, les méthodes synchrones devraient cacher tout cela, et ressembler et fonctionner comme des méthodes ordinaires.
Il s'agit de la méthode de base 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 fige indéfiniment.
Version 2 :
Hmm Peut-être que la tâche n'a pas été lancée ?
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
Cela 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 fonctionne. Donc, 2 et 3 sont les mauvais outils. Mais 1 ? Qu'est-ce qui ne va pas avec 1 et quelle est la différence avec 4 ? Pourquoi 1 provoque-t-il un blocage ? Y a-t-il un problème avec l'objet tâche ? Y a-t-il un blocage non évident ?
0 votes
Avez-vous réussi à obtenir une explication ailleurs ? Les réponses ci-dessous n'apportent pas vraiment d'éclaircissement. J'utilise en fait .net 4.0 et non 4.5/5, je ne peux donc pas utiliser certaines des opérations mais je rencontre les mêmes problèmes.
3 votes
@amadib, les ver.1 et 4 ont été expliqués dans les réponses [rpvided]. Les ver.2 et 3 essaient de recommencer une tâche déjà commencée. Postez votre question. Il n'est pas clair comment vous pouvez avoir des problèmes d'async/await dans .NET 4.5 sur .NET 4.0.
2 votes
La version 4 est la meilleure option pour Xamarin Forms. Nous avons essayé les autres options, mais elles n'ont pas fonctionné et nous avons rencontré des blocages dans tous les cas.
0 votes
Merci ! La version 4 a fonctionné pour moi. Mais est-ce que ça fonctionne toujours de manière asynchrone ? Je suppose que oui, car le mot clé asynchrone est là.