我使用 Pcap.Net 进行流量监控,我需要它来接收数据包,直到用户请求取消。我以这种方式(简化)创建监控任务:
var task1 = Task.Run(() => { communicator.ReceivePackets(0, PacketHandlerCallback); } /*, token*/);
这里 0
表示 ReceivePackets
的执行永远不会结束,PacketHandlerCallback
是一个将为每个接收到的数据包执行的方法。 ReceivePackets
是同步的,不支持取消。一般来说,在我的问题中,它可能是我们无法编辑代码的任何其他无穷无尽的同步方法。
问题是如何停止这个方法的执行?
仅将取消 token 传递给任务没有帮助,因为我们还应该明确检查是否请求取消,例如。 G。通过调用
token.throwIfCancellationRequested()
。将 token 传递给回调方法也不是解决方案,因为在收到新数据包之前不会调用此方法,但我想在取消后立即停止我的任务。
使用
BackgroundWorker
会导致同样的问题,因为我们应该检查CancellationPending
。创建定期检查取消请求的
task2
然后编写var task = Task.WhenAny(task1, task2)
无济于事,因为ReceivePackets
仍将执行。
我应该使用 Thread.Abort()
还是有其他优雅的解决方案?
SO 上有关于 TPL 的类似问题,但我找不到任何简单而有用的答案。
最佳答案
在无法取消的情况下,比 Thread.Abort 更好的解决方案是将不可取消的代码放入一个您可以终止的单独进程中。
这可以保证释放线程持有的所有资源,因为操作系统将释放任何持有的非托管操作系统资源,如进程退出时的句柄,如果中止线程或使用单独的线程,则不会出现此行为您关闭的 AppDomain。
当你编写了第二个过程时,你可以使用类似 WCF over named pipes 的东西因此您可以像处理流程中的任何其他正常功能一样与外部流程进行交互。
关于c# - 中止包含永无止境的库方法的任务(无法检查取消请求),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44345795/