Motif Timeout sur la tâche asynchrone basé sur la méthode en C#
Autant que je sache, il s'agit de deux modèles possibles pour mettre en œuvre un délai d'attente de tâche asynchrone basé sur des méthodes:
Intégré dans le délai
public Task DoStuffAsync(TimeSpan timeout)
Cette approche est plus difficile à mettre en œuvre car il n'est pas facile à mettre en œuvre un mondiale délai d'attente pour l'ensemble de la pile d'appel. Par exemple, une Web API contrôleur reçoit une requête HTTP et il appelle DoStuffAsync
, et que l'appelant veut un délai global de 3 secondes.
Qui est, de chaque intérieur async appel de la méthode devra faire l'objet de la soustraction de déjà utilisé du temps...
Pas intégré dans le délai
public Task DoStuffAsync(CancellationToken cancellationToken)
..........
CancellationTokenSource cancellationSource = new CancellationTokenSource();
Task timeoutTask = Task.Delay(3000);
if(await Task.WhenAny(DoStuffAsync(cancellationTokenSource), timeoutTask) == timeoutTask)
{
cancellationSource.Cancel();
throw new TimeoutException();
}
Ce qui semble être le plus fiable et le plus facile à mettre en œuvre le modèle. Le premier appelant définit un délai global, et si il sorties de temps, toutes les opérations en cours sera annulée. En outre, il fournit un jeton d'annulation de l'appelant immédiat et intérieure appels partagent le même jeton d'annulation de référence. Ainsi, si le haut de l'appelant sorties de temps, il sera en mesure d'annuler toute thread de travail.
L'ensemble de la question
Est-il un modèle que je suis absent ou, suis-je dans le droit chemin si je développe des Api à l'aide de la pas intégré dans le délai?
OriginalL'auteur Matías Fidemraizer | 2014-09-05
Vous devez vous connecter pour publier un commentaire.
Avertissement:
Lorsque nous parlons d'un
Task
en annulation de l'état, nous voulons dire que nous annuler l'opération, car elle procède. Cela pourrait ne pas être le cas ici quand on parle d'annulation, comme nous l'avons jetez simplement la tâche si elle terminée après l'intervalle de temps spécifié. Ce point est discuté à mesure de Stephan Toubs l'article ci-dessous pourquoi la BCL ne fournit pas de OOTB caractéristiques de l'annulation d'une opération en cours.De l'approche commune, je vois aujourd'hui est le pas de construire-dans approche et celle que je me retrouve à l'utiliser principalement pour mettre en œuvre une annulation de mécanisme. Il est certainement le plus facile des deux, en laissant le plus haut cadre à la charge de l'annulation en passant à l'intérieur des cadres le jeton d'annulation. Si vous vous trouvez en répétant ce modèle, vous pouvez utiliser le connu
WithCancellation
méthode d'extension:C'est à partir de Stephan Toubs Comment puis-je annuler non résiliables opérations asynchrones? qui n'est pas exactement le spot sur de ce que vous demandez, mais vaut la peine d'être lu.
La l'Annulation de Tâches docs préciser deux façons de l'annulation de tâches:
Modifier
Que pour vous concernent avec l'aide d'un
TimeSpan
pour spécifier l'intervalle souhaité, utilisez les la surcharge deCancellationTokenSource
constructeur qui prend unTimeSpan
paramètre:Je pense que l'OP comprend la sémantique de la "annulation" dont on parle ici. Mais peu modifier ma réponse pour que ce soit clair.
Parfait! Merci
Est-il possible de réaliser cela pour de multiples tâches (à l'aide de
Task.WhenAll
)? Je l'ai essayé, mais le fait de lancer l'exception d'une tâche causé les autres tâches à être abandonnée. PS - je besoin pour utiliserawait
plutôt queTask.Run
car j'ai besoin de laHttpContext
dans les tâches.Ne Étienne Taub l'article que vous avez fournis ci-dessus et à l'écrit en 2012 (blogs.msdn.microsoft.com/pfxteam/2012/10/05/...) s'applique vraiment, encore aujourd'hui en 2019? N'avons-nous pas une meilleure façon maintenant ou? Désolé demande simplement parce que je lis à propos de beaucoup de se plaindre lors de l'utilisation de NetworkStream de ReadAsync et WriteAsync et beaucoup de plaintes sont à partir de ce moment plust à la documentation de Microsoft sur ce suce
OriginalL'auteur Yuval Itzchakov
Pendant que vous peut réutilisation
WithCancellation
pour les annulations et les délais d'attente je pense que c'est un overkill pour ce que vous avez besoin.Un moyen plus simple et plus claire de la solution pour un
async
opération de délai d'attente serait deawait
à la fois du fonctionnement et de l'un délai d'attente de tâche à l'aide deTask.WhenAny
. Si le délai d'attente de tâche se termine en premier, vous vous retrouvez avec un délai d'attente. Sinon, l'opération s'est terminée avec succès:Utilisation:
Si vous préférez ne pas lever une exception (comme je le fais) c'est encore plus simple, il suffit de retourner la valeur par défaut:
À l'aide d'une exception, c'est la façon la .Net-library fonctionne. Il jette également lorsqu'il y a annulation. Je ne préfère éviter ces exceptions mais au lieu d'un n-uplet-je retourner à la valeur par défaut (pour la réponse). Une autre option serait d'utiliser le
TryX(out result)
paradigme.tout endroit où cela est d'expliquer comment mettre en œuvre NetworkStream de ReadAsync et WriteAsync annulation. Je suis pas où la, garde verrouillé sur moi tout le temps que par ce post stackoverflow.com/questions/54816114/...
qu'entendez-vous mettre en œuvre? Vous avez votre propre
NetworkStream
? L'un est .NET ne modifie pasWriteAsync
/ReadAsync
, de sorte que vous obtenez leStream
de mise en œuvre qui ne regarde que laCancellationToken
si c'est annulé avant le début de l'opération. Ainsi, ces opérations ne sont pas vraiment annulable.Non, je parle NetworkStream .NET. Je suis à essayer de comprendre comment utiliser correctement WriteAsync et ReadAsync que je ne peux pas utiliser la mise en réseau sur le thread principal de Xamarin.Les formulaires. Donc, je dois utiliser WriteAsync pour obtenir des informations à distance et puis si il y a réponse, utilisez ReadAsync à lire la réponse que j'ai eu en retour.
OriginalL'auteur i3arnon