我试图使用令牌来取消由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没有被处理。我从微软网站开始开发程序,它的功能非常完美。我想我像他们一样做着所有事情,但不幸的是,它并不像它应该那样工作。
快速问题,你有“启用只是我的代码”启用? – WBuck
是的,我已启用它。 – Dzejkob