【发布时间】:2017-11-04 20:39:22
【问题描述】:
我使用 Pcap.Net 进行流量监控,我需要它来接收数据包,直到用户请求取消。我以这种方式创建监控任务(简化):
var task1 = Task.Run(() => { communicator.ReceivePackets(0, PacketHandlerCallback); } /*, token*/);
这里0 表示ReceivePackets 的执行永远不会结束,PacketHandlerCallback 是一个将为每个接收到的数据包执行的方法。 ReceivePackets 是同步的,不支持取消。一般来说,在我的问题中它可能是我们无法编辑的任何其他无限同步方法。
问题是如何停止这个方法的执行?
仅将取消令牌传递给任务并没有帮助,因为我们还应该明确检查是否请求取消,例如。 G。致电
token.throwIfCancellationRequested()。将令牌传递给回调方法也不是解决方案,因为在收到新数据包之前不会调用此方法,但我想在取消后立即停止我的任务。
使用
BackgroundWorker会导致同样的问题,因为我们应该检查CancellationPending。创建定期检查取消请求的
task2然后写入var task = Task.WhenAny(task1, task2)没有帮助,因为ReceivePackets仍将执行。
我应该使用Thread.Abort() 还是有其他优雅的解决方案?
SO上有关于TPL的类似问题,但我找不到任何简单而有用的答案。
【问题讨论】:
-
您可能需要考虑设置
communicator.NonBlocking = true,然后重写您的代码以在非阻塞模式下使用communicator.ReceiveSomePackets,这样您就不必担心代码挂了,您可以当你想把所有东西都清理干净的时候,把通讯器扔掉。 -
@Scott 很好的建议,谢谢。我知道这不是问题所在,但这正是我现在需要的。您能否确认如果我为非阻塞通信器写
while(true) { communicator.ReceiveSomePackets(/*args*/); token.throwIfCancellationRequested(); },我不会丢失在取消请求检查期间可以接收到的数据包? -
以前从未使用过该库,我只是检查了来源并看到了该属性和该属性的注释。
标签: c# asynchronous task-parallel-library cancellation pcap.net