2017-06-06 3 views
0

Ich versuche Token zu verwenden, um Task abgebrochen von Task.Run gestartet. Ich nahm Muster von Microsoft-Website: https://msdn.microsoft.com/pl-pl/library/hh160373(v=vs.110).aspxProgramm werfen OperationCanceledException trotz abfangen

Dies ist mein Code:

public static class Sender 
{ 

    public static async Task sendData(NetworkController nc) { 
     await Task.Run(() => { 
      IPEndPoint endPoint = new IPEndPoint(nc.serverIp, nc.dataPort); 
      byte[] end = Encoding.ASCII.GetBytes("end"); 
      while (true) { 
       if (Painting.pointsQueue.Count > 0 && !nc.paintingSenderToken.IsCancellationRequested) { 

        byte[] sendbuf = Encoding.ASCII.GetBytes(Painting.color.ToString()); 
        nc.socket.SendTo(sendbuf, endPoint); 

        do { 
         sendbuf = Painting.pointsQueue.Take(); 
         nc.socket.SendTo(sendbuf, endPoint); 
        } while (sendbuf != end && !nc.paintingSenderToken.IsCancellationRequested); 

       } 
       else if (nc.paintingSenderToken.IsCancellationRequested) { 
        nc.paintingSenderToken.ThrowIfCancellationRequested(); 
        return; 
       } 
      } 
     }, nc.paintingSenderToken); 
    } 
} 

Und hier beginne ich diese Aufgabe:

public void stopController() { 
     try { 
      paintingSenderTokenSource.Cancel(); 
      senderTask.Wait(); 
     } catch(AggregateException e) { 
      string message = ""; 
      foreach (var ie in e.InnerExceptions) 
       message += ie.GetType().Name + ": " + ie.Message + "\n"; 
      MessageBox.Show(message, "Przerwano wysylanie"); 
     } 
     finally { 
      paintingSenderTokenSource.Dispose(); 
      byte[] message = Encoding.ASCII.GetBytes("disconnect"); 
      IPEndPoint endPoint = new IPEndPoint(serverIp, serverPort); 
      socket.SendTo(message, endPoint); 
      socket.Close(); 
      mw.setStatus("disconnected"); 
     } 

    } 

    public async void initialize() { 
     Task t = Reciver.waitForRespond(this); 
     sendMessage("connect"); 
     mw.setStatus("connecting"); 
     if (await Task.WhenAny(t, Task.Delay(5000)) == t) { 
      mw.setStatus("connected"); 
      Painting.pointsQueue = new System.Collections.Concurrent.BlockingCollection<byte[]>(); 
      senderTask = Sender.sendData(this); 
     } 
     else { 
      mw.setStatus("failed"); 
     } 
    } 
} 

In initialize() Methode, die ich bin auf die Antwort von der Warte Server und wenn ich es bekomme, starte ich einen neuen Thread in dieser sendData() Methode. Es ist in der statischen Klasse, Code sauberer zu machen. Wenn ich diesen Thread stoppen möchte, rufe ich stopController() Methode. In Microsoft-Website können wir lesen:

Die CancellationToken.ThrowIfCancellationRequested Methode löst eine OperationCanceledException Ausnahme, die in einem catch-Block behandelt wird, wenn der aufrufende Thread die Task.Wait Methode aufruft.

Aber mein Programm bricht auf nc.paintingSenderToken.ThrowIfCancellationRequested();, die in ‚senddata()‘ Methode ist und der Fehler sagt, dass OperationCanceledException nicht behandelt wurde. Ich habe das Programm von Microsoft Website gestartet und es funktioniert perfekt. Ich denke, ich mache alles wie sie, aber leider funktioniert es nicht so, wie es sollte.

+0

Schnelle Frage, haben Sie "Aktivieren Sie nur meinen Code" aktiviert? – WBuck

+0

Ja, ich habe es aktiviert. – Dzejkob

Antwort

0

Möglicherweise haben Sie "Nur Code aktivieren" aktiviert. Um die Einstellungen zu gehen zu finden:

Extras => Einstellungen => Debuggen => Allgemein => Just My-Code aktivieren

Wenn dieses Kontrollkästchen aktiviert ist können Sie es deaktivieren Sie die Option und dann laufen Ihre Bewerbung erneut.

+0

Nun, es hat geholfen, aber nicht genau. Programm bricht jetzt nicht ab, aber es friert bei 'senderTask.Wait()' ein. In Debuuger kann ich sehen, dass Thread noch läuft. – Dzejkob

Verwandte Themen