2017-06-06 56 views
0

我試圖使用令牌來取消由Task.Run啓動的任務。我把模式從微軟的網站:https://msdn.microsoft.com/pl-pl/library/hh160373(v=vs.110).aspx程序拋出OperationCanceledException(儘管捕獲它)

這是我的代碼:

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); 
    } 
} 

在這裏,我開始這個任務:

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"); 
     } 
    } 
} 

initialize()方法我在等待從響應服務器,如果我得到它,我在這個sendData()方法中開始新的線程。它在靜態類中使代碼更清潔。如果我想停止此線程,請撥打stopController()方法。在微軟的網站上,我們可以讀到:

的CancellationToken.ThrowIfCancellationRequested方法拋出時調用線程調用Task.Wait方法是在catch塊處理的OperationCanceledException例外。

但是我的程序在nc.paintingSenderToken.ThrowIfCancellationRequested();中斷了,它在'sendData()'方法中,錯誤表示OperationCanceledException沒有被處理。我從微軟網站開始開發程序,它的功能非常完美。我想我像他們一樣做着所有事情,但不幸的是,它並不像它應該那樣工作。

+0

快速問題,你有「啓用只是我的代碼」啓用? – WBuck

+0

是的,我已啓用它。 – Dzejkob

回答

0

您可能已啓用「啓用只是我的代碼」。 要查找的設置,請訪問:

工具=>選項=>調試=>常規=>啓用僅我的代碼

如果這個複選框被選中你能取消選中它,然後運行你的申請再次。

+0

那麼它幫助,但不是沒有。程序現在不會中斷,但會凍結'senderTask.Wait()'。在debuuger中,我可以看到該線程仍在運行。 – Dzejkob

相關問題