2016-10-14 2 views
-1

In diesem Code, wenn ich die Start-Funktion und danach mit einem gebundenen "Abbrechen" -Button starte, werde ich versuchen, die Aufgabe zu stoppen, er gab mir eine Ausnahme vom Typ "System.OperationCanceledException" sagen, dass nicht behandelt wurde im Benutzercode ...Warum throwIfCancellationRequested wird nicht in meinem try catch-Block behandelt?

Warum mein Versuch, Block zu fangen nicht damit umgehen? Wie kann ich diese Aufgabe über eine Schaltfläche "Abbrechen" in meiner Ansicht stoppen?

namespace LauncherWPF.ViewModel 
{ 
    /// <summary> 
    /// This class contLineageViewModel ains properties that a View can data bind to. 
    /// </summary> 
    public class : ViewModelBase 
    { 
     private CancellationTokenSource _tokenSource; 
     private CancellationToken _cancellationToken; 

     /// <summary> 
     /// Initializes a new instance of the LineageViewModel class. 
     /// </summary> 
     public LineageViewModel() 
     {     
     } 

     public void Start() 
     { 

      _tokenSource = new CancellationTokenSource(); 
      _cancellationToken = _tokenSource.Token; 

      Debug.Write("TaskStarted"); 

      try 
      { 
       Task.Run(() => 
       { 
        for (var i = 0; i < 100; ++i) 
        { 
         _cancellationToken.ThrowIfCancellationRequested(); 
         Debug.Write("Progress " + i); 
         for (var j = 0; j < 100; ++j) 
         { 
          Debug.Write("Updated " + j); 
          Thread.Sleep(50); 
         } 
        } 
       }, _cancellationToken); 
      } 
      catch (OperationCanceledException e) 
      { 
       Debug.Write("Canceled"); 
      } 
     } 

     public void Cancel() 
     { 
      //not working 
      _tokenSource.Cancel(); 

     } 
    } 
} 
+0

Siehe auch https://stackoverflow.com/questions/28629405/exception-in-async-methods-is-not-caught –

+0

Sorry, ich wusste nicht, dass mein Problem war mit der asynchronen Aufgabe verwandt, so war es nicht in der Lage, es mit dem richtigen Begriff zu suchen ... deshalb habe ich diese Frage erstellt. Fühlen Sie sich frei, es abzustimmen ... – exSnake

Antwort

0

Da die Task asynchron ausgeführt wird, nachdem Sie den try/catch-Block beendet haben.

Versuchen Sie stattdessen:

Task.Run(() => 
{ 
    try 
    { 
    for (var i = 0; i < 100; ++i) 
    { 
     _cancellationToken.ThrowIfCancellationRequested(); 
     Debug.Write("Progress " + i); 
     for (var j = 0; j < 100; ++j) 
     { 
      Debug.Write("Updated " + j); 
      Thread.Sleep(50); 
     } 
    } 
    } 
    catch (OperationCanceledException e) 
    { 
     Debug.Write("Canceled"); 
    } 
}, _cancellationToken); 

noch besser, verlassen Sie sich nicht auf Ausnahmen für den normalen Fluss. Sie könnten leicht umschreiben als:

if(_cancellationToken.IsCancellationRequested) 
{ 
    Console.WriteLine("cancelled"); 
    break; 
} 
+0

Also das Recht, warum es zu handhaben ist nur zu überprüfen, ob die Stornierung angefordert wurde? – exSnake

+0

Ausnahmen kosten viel. Überprüfen der Eigenschaften nicht. Ausnahmen sollten nur für Ausnahmefälle und nicht als Teil der normalen Ausführung verwendet werden. – spender

+1

_ "Verlassen Sie sich nicht auf Ausnahmen für den normalen Fluss" _ - das ist ein guter Rat. Außer es ist hier nicht anwendbar. Das Abbrechen der Aufgabe ist kein "normaler Fluss", und die TPL wurde speziell für den Betrieb in Verbindung mit "TaskCanceledException" entwickelt. Ohne die Ausnahme wird das 'Task'-Objekt selbst normal beendet, anstatt in den Zustand 'Canceled' versetzt zu werden. In einigen Code ist dies in Ordnung, aber die meiste Zeit ist es wichtig zu wissen, ob die "Task" normal abgeschlossen oder nicht (versucht, die Aufgabe abzubrechen wird Ihnen nicht sagen, dass aufgrund des Rennens), und eine Ausnahme ist wie Das ist erledigt. –

Verwandte Themen