我試圖使用令牌來取消由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