Wie zu Warten, für Abgebrochene Aufgabe zu Beenden?
Ich natürlich nicht weiß, was ich Tue, wenn es um die parallele Programmierung mit .NET 4.0. Ich habe eine einfache Windows-Anwendung, die eine Aufgabe startet, um einige der sinnlosen Arbeit (die Ausgabe von zahlen 1-1000). Ich habe eine beträchtliche pause in der Hälfte Weg durch simulieren eines lang andauernden Prozesses. Während dieser langen pause stattfindet, wenn ich drücken Sie die Stop-Taste, wird die zugehörige event-handler ruft die Cancel-Methode des CancellationTokenSource. Ich will nicht zu tun, jede weitere Verarbeitung (in diesem Fall die Ausgabe einer Nachricht) in der Haltestellen-button-event-handler, bis der abgebrochene Aufgabe wird erledigt, mit der aktuellen iteration. Wie mache ich das? Ich habe versucht, mit Aufgabe.WaitAll, etc in der Stop-button-event-handler, aber nur wirft eine unbehandelte AggregateException. Hier ist der code, die helfen, zu erklären, mein problem, wenn ausgeführt, wie oben beschrieben:
private Task t;
private CancellationTokenSource cts;
public Form1()
{
InitializeComponent();
}
private void startButton_Click(object sender, EventArgs e)
{
statusTextBox.Text = "Output started.";
//Create the cancellation token source.
cts = new CancellationTokenSource();
//Create the cancellation token.
CancellationToken ct = cts.Token;
//Create & start worker task.
t = Task.Factory.StartNew(() => DoWork(ct), ct);
}
private void DoWork(CancellationToken ct)
{
for (int i = 1; i <= 1000; i++)
{
ct.ThrowIfCancellationRequested();
Thread.Sleep(10); //Slow down for text box outout.
outputTextBox.Invoke((Action)(() => outputTextBox.Text = i + Environment.NewLine));
if (i == 500)
{
Thread.Sleep(5000);
}
}
}
private void stopButton_Click(object sender, EventArgs e)
{
cts.Cancel();
Task.WaitAll(t); //this doesn't work :-(
statusTextBox.Text = "Output ended.";
}
private void exitButton_Click(object sender, EventArgs e)
{
this.Close();
}
Jede Hilfe bei diesem würde sehr geschätzt werden. Vielen Dank im Voraus.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Würden Sie normalerweise benutzen Sie einfach
Task.Wait
(stattWaitAll
), als es eine einzelne Aufgabe. und dann die Ausnahme behandelt entsprechend:Wenn Sie kündigen, eine
Task
, dieOperationCanceledException
erhalten-verpackt in einerAggregateException
und geworfen werden, sobald Sie anrufenWait()
oder versuchen Sie, die AufgabeResult
(wenn es einTask<T>
).Rein zu Ihrer information - Dies ist ein Ort, vor allem angesichts dessen, was du hier tust, wo C# 5 vereinfacht die Dinge. Mit dem neuen async-Unterstützung, Sie können dies schreiben als:
ae.Handle(x => x is OperationCanceledException);
ich denke, Reed möglicherweise eine Erweiterung Methode ermöglicht die Typ-parameter.Sorry, nicht genug Ruf, fügen Sie einfach eine Frage als Kommentar zu dieser Antwort. Ich wollte mal Fragen, wie ein work-around als eine Antwort.
Nicht den code in die Antwort setzen auf irgendeine Art von Benutzeroberfläche optimieren, um den Benutzer vor dem starten mehr als ein hintergrund-Prozess zu einer Zeit? Das ist immer ein problem, natürlich.
Hier präsentiere ich Euch eine alternative, die die Frage beantworten, die angegeben ist. Es zeigt, wie zu warten, bis die Abmeldung zu beenden. Er tut dies in einer Weise, dass lässt immer noch den UI-Schraube Dinge, wenn es nicht gut gelungen, aber hat code, der eigentlich wartet, nach der Absage, wenn es das ist, was wirklich gebraucht wird. Dies ist ein Auszug aus einem größeren C# - Klasse:
Dieser code beruht auf ein Ereignis-Objekt, um zu signalisieren, dass die Aufgabe ist meist fertig. Die WorkerMethod() code hat sich nicht zurück-noch nicht, aber alle nützlich, die Arbeit ist getan, wenn das Ereignis signalisiert wird.
Ich nicht eine Stop () - Funktion, weil, wie ich diesen code verwenden. Der code dazu das warten würde nur gehen, dass die Stop () - Funktion, wenn das war, wie der code arbeiten muss.
Ja, Sie können nicht mit einem regelmäßigen Wait () - Funktion aufgrund der Stornierung Ausnahme. Aber die akzeptierte Antwort ist mehr ein work-around, nichts für ungut (und vielleicht bin ich falsch?).