【发布时间】:2017-11-07 09:06:14
【问题描述】:
我正在尝试使用令牌来取消由 Task.Run 启动的任务。我从 microsoft 网站获取了模式:https://msdn.microsoft.com/pl-pl/library/hh160373(v=vs.110).aspx
这是我的代码:
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() 方法。在微软网站我们可以阅读:
当调用线程调用 Task.Wait 方法时,CancellationToken.ThrowIfCancellationRequested 方法会引发 OperationCanceledException 异常,该异常在 catch 块中进行处理。
但是我的程序在“sendData()”方法中的nc.paintingSenderToken.ThrowIfCancellationRequested(); 上中断,并且错误表明未处理 OperationCanceledException。我从微软网站启动程序,它运行良好。我想我所做的一切都像他们一样,但不幸的是它并没有像它应该的那样工作。
【问题讨论】:
-
快速提问,您是否启用了“仅启用我的代码”?
-
是的,我已启用它。
标签: c# wpf multithreading exception-handling