2017-06-06 84 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

相关问题