Relais de Commande permet d'exécuter et d'une Tâche
je veux commencer une tâche lorsqu'un relais de commande est appelée, cependant je souhaite désactiver le bouton tant que la tâche est en cours d'exécution
prendre cet exemple
private ICommand update;
public ICommand Update
{
get
{
if (update == null)
{
update = new RelayCommand(
param => Task.Factory.StartNew(()=> StartUpdate()),
param => true); //true means the button will always be enabled
}
return update;
}
}
quelle est la meilleure façon de vérifier si la tâche est en cours d'exécution?
voici ma solution, mais ne sais pas si c'est la meilleure façon
class Vm : ObservableObject
{
Task T;
public Vm()
{
T = new Task(() => doStuff());
}
private ICommand myCommand;
public ICommand MyCommand
{
get { return myCommand ?? (myCommand = new RelayCommand( p => { T = new Task(() => doStuff()); T.Start(); }, p => T.Status != TaskStatus.Running)); }
}
private void doStuff()
{
System.Threading.Thread.Sleep(5000);
}
}
Mise à jour : Chaque réponse ici fonctionne très bien, mais encore ils ne sont pas d'accord les uns avec les autres, et j'ai juste atteint 100 points de réputation , je commence une prime à chaque fois que j'atteins 100, donc ce que je suis à la recherche d'une mise en œuvre optimale de non fuite de mémoire asynchrone RelayCommand qui s'exécute au sein d'une tâche .net 4.0
il l'habitude de travailler avec des Tâches.IsCompleted, à l'aide de
T.Status != TaskStatus.Running
est la meilleure optionOriginalL'auteur FPGA | 2013-11-24
Vous devez vous connecter pour publier un commentaire.
Je pense, vous pouvez utiliser cette application de AsyncCommand.
OriginalL'auteur Vladimir Almaev
Je vous recommande fortement d'éviter
new Task
ainsi queTask.Factory.StartNew
. La bonne façon de commencer une tâche asynchrone sur un thread d'arrière-plan estTask.Run
.Vous pouvez créer un asynchrones
RelayCommand
facilement à l'aide de ce modèle:RelayCommand
ne pas accepter uneasync
lambda (c'est à dire,Func<Task>
); le lambda est là pour envelopper leasync
code dans unasync void
(c'est à dire,Action
). LeTask.Run
n'est présent que parce que les op le code original est également en cours d'exécutionStartUpdate
sur un thread d'arrière-plan; dans la situation idéale (async
tous les sens), leTask.Run
ne serait pas nécessaire.Alors qu'est-ce que le besoin de le marquer comme async? Ne pourrait-on pas appeler relancer un Événement à l'intérieur de la Tâche.Exécuter en l'enveloppant d'Élever un Événement à l'intérieur du Répartiteur BeginInvoke?
Hormis le fait que l'utilisation directe de
Dispatcher
est une odeur de code, je ne pense pas que cela fonctionnera de la façon dont vous pensez. Vous avez besoin d'uneasync void
méthode à un certain point.OriginalL'auteur Stephen Cleary
Donc votre solution pour utiliser RelayCommand fonctionne presque. Le problème est que l'INTERFACE utilisateur ne sera pas mise à jour immédiatement après la tâche en cours d'exécution. C'est parce que quelque chose a besoin de déclencher le ICommand de l'événement CanExecuteChanged pour l'INTERFACE utilisateur de mettre à jour correctement.
Une façon de résoudre ce problème par la création d'un nouveau type de ICommand. Par exemple:
Maintenant votre modèle de vue peut faire quelque chose comme
Ou vous pourriez faire votre doStuff fonction "async" fonction de la façon
StartNew
est dangereux (comme je l'explique sur mon blog), et 2) la mise en œuvre deCanExecuteChanged
fuites de mémoire.1) Ma mise en œuvre de AsyncRelayCommand n'utilise pas la Tâche.StartNew, j'étais simplement en adaptant l'exemple de code pour le rendre compréhensible que possible. 2) ce que j'ai lu, c'est fixe en 4.5 et est axé sur le changement de contrôle, ou ICommandSource, non sur la modification de la mise en œuvre de ICommand.
OriginalL'auteur MerickOWA
Vous pourriez avoir une variable statique
IsRunning
, que vous pouvez définir à True lors de votre tâche commence, à false quand il se termine, et juste lier bouton activé à l'état de laIsRunning
eh bien, quelqu'un a besoin de savoir à propos de quelque chose ... comment voulez-vous faire autrement? 🙂
peut-être en faisant de la tâche globale?, il serait inquiétant parce que j'ai beaucoup de commandes et j'ai besoin de boutons pour être désactivées tant que la tâche est en cours d'exécution
Statique drapeau doit être utilisé uniquement dans le plus simple des scénarios, il s'approche très rapidement tombe à l'eau lorsque les choses deviennent plus complexes.
cela ressemble à un scénario simple pour moi. Sinon, qu'est-ce que vous êtes suggérant? semble que je suis un downvote, et l'OP n'a jamais eu une alternative ...
OriginalL'auteur Noctis
J'essaie d'éviter le Prisme de la bibliothèque de garder mon contrôle simple que possible du point de vue du mont de référence assemblées et j'ai fini avec cette solution
Semble bien fonctionner. (si vous n'avez pas besoin de passer commandParameter). Malheureusement, c'est toujours un problème.
RelayCommand classe hérite de ICommand
OriginalL'auteur stenly