Comment puis-je attendre une méthode asynchrone sans un async modificateur dans cette méthode parent?
J'ai une méthode que j'ai envie d'attendre mais je ne veux pas provoquer un effet domino penser n'importe quoi peut appeler cette méthode d'appel et l'attendent. Par exemple, j'ai cette méthode:
public bool Save(string data)
{
int rowsAffected = await UpdateDataAsync(data);
return rowsAffected > 0;
}
Je vais appeler:
public Task<int> UpdateDataAsync()
{
return Task.Run(() =>
{
return Data.Update(); //return an integer of rowsAffected
}
}
Cela ne marchera pas, parce que je dois mettre "async" dans la signature de la méthode pour Save()
et puis je ne peux pas retourner bool
j'ai à faire Task<bool>
mais je ne veux pas que quelqu'un en attente de la Save()
méthode.
Est-il une manière que je peux suspendre l'exécution de code comme attendre ou d'une certaine façon, attendent le code sans l'async modificateur?
Je serais assez ennuyé si vous m'avez donné l'accès à un
Save
méthode qui a bloqué mon thread, ce qui m'oblige à placer l'appel dans un Task
, ce qui est exactement ce que vous pourriez avoir retourné moi en premier lieu. Juste pour dire.OriginalL'auteur Neal | 2013-06-01
Vous devez vous connecter pour publier un commentaire.
C'est un peu comme demander "comment puis-je écrire une application à l'aide de C#, mais sans prendre une dépendance sur tout type de .NET runtime?"
Réponse courte: ne pas le faire.
Vraiment, ce que vous faites ici est de prendre naturellement méthode synchrone (
Update
), faisant apparaître un asynchrones en cours d'exécution sur un thread du pool (UpdateDataAsync
), et puis vous êtes désireux de bloc afin de rendre la méthode asynchrone apparaissent synchrone (Save
). Sérieux drapeaux rouges.Je vous recommande de lire attentivement Stephen Toub la célèbre paire de billets de blog dois-je exposer asynchrone des wrappers pour mes méthodes synchrones et dois-je exposer synchrone des wrappers pour mes méthodes asynchrones. La réponse à ces deux questions est "non", bien que Stephen Toub explique plusieurs options pour le faire si vous devez vraiment.
Que "vraiment" devrait être réservé à niveau de l'application. Je suppose que ces méthodes (
Update
,UpdateDataAsync
, etSave
) dans les différentes couches de l'application (par exemple, des données /data /modèle de vue). Les données /service de données des couches ne doit pas faire synchrone/asynchrone conversions. Le modèle de vue (applications spécifiques) est le seul qui a une excuse pour faire ce genre de conversion, et il ne doit le faire que comme un dernier recours.Pourquoi ne pas le faire de manière asynchrone?
Vous pouvez écrire asynchrone en cas de test?
Oui. Toutes les grandes infrastructures de test unitaire (xUnit, MSTest, NUnit) ont pris en charge
async Task
unité de méthodes d'essai depuis 2012.OriginalL'auteur Stephen Cleary
Edit: la réponse était devant la Tâche.La course a été ajouté. Avec ce supplément de contexte, le scénario est mieux décrit comme "ne fais pas ça".
Vous pouvez accéder à
.Result
ou de l'utilisation.Wait()
, mais vous devez connaître la façon dont la tâche est d'abord mises en œuvre. En particulier, vous devez savoir si elle utilise sync-contexte. La raison de ce qui est important, c'est que si elle pouvait impasse immédiatement, parce que certains de synchronisation-contextes doivent le contexte de l'appel à sortir complètement (par exemple, MVC de synchronisation-contexte doit quitter le contrôleur d'action de la méthode).Pour se prémunir contre c'est dur, mais vous devriez toujours explicitement spécifier un timeout avec un appel à
.Wait()
- juste au cas où.avec l'edit, je dirais juste "ne pas faire" - ajout d'un thread pour aucune raison que ce soit. Vous pourriez aussi bien le faire que le travail sur le thread qui va être assis en attente.
Marc est tout à fait juste; essentiellement ce que vous faites ici est d'embaucher quelqu'un pour attendre sur votre nom, puis attendre jusqu'à ce qu'ils ont fait leur travail, qui est en attente sur votre compte. Vous ne voudriez pas embaucher quelqu'un pour le faire que dans la vraie vie, il ne faut pas le faire ici. Si vous avez besoin d'attendre de façon synchrone pour la tâche à faire, puis faire; si vous voulez continuer à faire le travail pendant que vous êtes en attente puis
await
.OriginalL'auteur Marc Gravell