2016-05-28 9 views
-1

ich diesen Code in meiner WPF-Anwendung habe:Aufgabe bleibt, ist im Betriebszustand nach dem Programm zu schließen

this.Closing += WindowOnClosing; 
CancellationTokenSource cts = new CancellationTokenSource(); 

private void func() 
{ 
    Task task = new Task.Factory.Start(() => 
    { 
     // long running code... 
    }), cts.Token); 
    await task; 
} 

private void WindowOnClosing(CancelEventArgs e) 
{ 
    cts.Cancel(); 
} 

Aber whenI das Fenster zu schließen, bleibt die Task-Zustand in läuft.

+0

http://stackoverflow.com/questions/10134310/how-to-cancel-a-task-in-await – mohsen

+1

Sie das Schließen abbrechen sollte in den 'WindowOnClosing' -Handler und legen Sie eine Fortsetzung für Ihre Aufgabe fest, die das Fenster zur Aufgabenlöschung schließt. –

Antwort

2

Zuerst Sie nicht StartNew in dieser Situation verwendet werden soll; Verwenden Sie stattdessen Task.Run. Wie ich auf meinem Blog erkläre, StartNew is dangerous. (Ich gehe davon aus, dass Ihr tatsächlicher Code StartNew verwendet, da new Task.Factory.Start keinen Sinn ergibt).

Zweitens, in meinem blog post on Delegate Tasks, I explain how the CancellationToken parameter of both StartNew and Run is misleading.

You keep using that cancellation token there. I do not think it means what you think it means.

Insbesondere hebt die CancellationToken nur der Scheduling des Teilnehmers; Es wird den Delegaten nicht selbst abbrechen. Sie müssen die Löschung in Ihrem eigenen Code reagieren:

private void func() 
{ 
    var token = cts.Token; 
    Task task = Task.Run(() => 
    { 
    ... 
    token.ThrowIfCancellationRequested(); // Occasionally do this. 
    ... 
    }); 
    await task; 
} 
+0

Das erklärt nur, warum er nie erwarten könnte, dass die Aufgabe abgebrochen wird, sobald es zu laufen beginnt. Das hat nicht erklärt, warum er den abgesagten Zustand auch nicht erwarten kann, wenn die Anwendung beendet ist. Es muss auf die Aufgabe gewartet werden –

-1

Ich denke, nach Aufgabe Abbrechen Sie für die Stornierung warten sollte:

task.Wait();

auch hier ist nützlich:

https://msdn.microsoft.com/en-us/library/dd997396%28v=vs.110%29.aspx

+2

Dies würde nichts anderes bewirken, als die Benutzeroberfläche seines Programms für einen längeren Zeitraum einzufrieren; es würde in keiner Weise die Hintergrundaufgabe tatsächlich abbrechen. – Servy

+0

Es ist nicht die Aufgabe abzubrechen, es ist nach dem Senden der Cancel-Flag und warten Sie einfach auf die Aufgabe zu reagieren, weil die Aufgabe vielleicht in Arbeit und nach dem ersten Mal sehen die Cancel Flag es die Aufgabe stoppen, nach all seinen in der msdn ... –

+0

Nein, das Problem mit dem OP-Code ist, dass er die Aufgabe nicht wirklich storniert. Es ist * wünschenswert *, dass er nicht synchron darauf wartet. Das Hinzufügen bricht nur den Code * noch mehr *. Es löst nicht das eigentliche Problem, und es ist aktiv schädlich mit oder ohne die tatsächliche Lösung hinzuzufügen. – Servy