Relais-Befehl ausführen kann und eine Aufgabe
ich soll eine Aufgabe zu beginnen, wenn ein relais-Befehl aufgerufen wird, aber ich wollen, deaktivieren Sie die Schaltfläche so lange, wie die Aufgabe ausgeführt wird
nehmen Sie dieses Beispiel
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;
}
}
was ist der beste Weg, um zu überprüfen, ob die Aufgabe ausgeführt wird?
hier ist meine Lösung aber nicht sicher, ob es der beste Weg,
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);
}
}
Update : Jede Antwort hier funktioniert gut, aber trotzdem sind Sie nicht einverstanden mit einander, und ich hatte gerade eine 100 Ruf , ich starte ein Kopfgeld, wenn ich bei 100 angekommen, was ich also Suche, ist eine Implementierung für eine optimale Speicher nicht undicht asynchrone RelayCommand, der ausgeführt wird, innerhalb einer Aufgabe .net 4.0
es wird nicht funktionieren mit der Aufgabe.IsCompleted, mit
T.Status != TaskStatus.Running
ist die beste optionInformationsquelleAutor FPGA | 2013-11-24
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich denke, Sie können mit dieser Umsetzung AsyncCommand.
InformationsquelleAutor Vladimir Almaev
Ich empfehle, dass Sie vermeiden
new Task
sowieTask.Factory.StartNew
. Der richtige start in einen asynchronen task auf einem hintergrund-threadTask.Run
.Können Sie eine asynchrone
RelayCommand
einfach mit diesem Muster:RelayCommand
nicht akzeptiert einasync
lambda (D. H.,Func<Task>
); die lambda ist dort wickeln Sie dasasync
- code in einasync void
(d.h.,Action
). DieTask.Run
ist nur vorhanden, weil die op ' s ursprüngliche code war auchStartUpdate
auf einem hintergrund-thread; in der idealen situation (async
alle Weg), dieTask.Run
wäre das nicht nötig.Dann was brauchen, um Sie zu markieren, als async? Konnte nicht rufen Sie Heben ein Ereignis in Aufgabe.Führen Sie durch die Verpackung Heben ein Ereignis in BeginInvoke des Dispatcher?
Abgesehen von der Tatsache, dass die direkte Nutzung von
Dispatcher
ist ein code smell, ich glaube nicht, dass es so funktionieren, wie Sie denken. Sie müssen einasync void
Methode irgendwann.InformationsquelleAutor Stephen Cleary
Also Ihre Lösung zu verwenden RelayCommand fast funktioniert. Das problem ist, dass die Benutzeroberfläche nicht sofort aktualisiert, nachdem die Aufgabe beendet wurde. Dies ist, da muss etwas auslösen, das ICommand das CanExecuteChanged-Ereignis, um das UI richtig aktualisiert.
Einen Weg, um dieses problem zu lösen, ist durch die Schaffung einer neuen Art von ICommand. Zum Beispiel:
Nun dein view-model etwas wie die folgenden
Oder Sie stellen Ihre Funktion doStuff "async" - Funktion wie so
StartNew
gefährlich ist (wie erkläre ich auf meinem blog), und 2) Ihre UmsetzungCanExecuteChanged
Speicherverluste.1) Meine Umsetzung AsyncRelayCommand nicht Aufgabe.StartNew, ich habe lediglich die Anpassung der Beispiel-code, um es so verständlich wie möglich. 2) Von was ich gelesen habe, ist dies Feste in 4.5 und konzentriert sich auf das ändern der Steuerelemente, oder ICommandSource, nicht verändern, wird bei der Implementierung des ICommand.
InformationsquelleAutor MerickOWA
Könnten Sie eine statische variable
IsRunning
, die Sie auf True setzen können, wenn Ihr task startet, wird auf false gesetzt, wenn es fertig ist, und nur binden, dass die Schaltfläche aktiviert, um den Zustand derIsRunning
gut, jemand braucht, um über etwas wissen ... wie würdet Ihr es anders machen? 🙂
vielleicht, indem Sie die Aufgabe global?, es wäre beunruhigend, weil ich habe eine Menge von Befehlen, und ich muss die Tasten deaktiviert werden, solange die zugehörige task ausgeführt wird
Ein statisches flag sollte nur verwendet werden, in den einfachsten Szenarien, ist dieser Ansatz sehr schnell auseinander fällt, wenn die Dinge beginnen immer komplexer.
das klingt wie ein einfaches Szenario für mich. Ansonsten, was ist es Sie empfehlen? scheint, wie ich habe ein downvote, und der OP bekam nie eine alternative ...
InformationsquelleAutor Noctis
Ich versuche zu vermeiden Prism-Bibliothek, um meine Steuerung einfach wie möglich aus der Sicht von mount of reference assemblies und ich landete mit dieser Lösung
Scheint gut zu funktionieren. (wenn Sie nicht brauchen, um passieren commandParameter in). Leider ist dies immer noch ein problem.
RelayCommand-Klasse erbt von ICommand
InformationsquelleAutor stenly