c# - 中止包含永无止境的库方法的任务(无法检查取消请求)

标签 c# asynchronous task-parallel-library cancellation pcap.net

我使用 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/

相关文章:

ios - 在 iOS 的后台线程中用同步请求替换异步请求?

c++ - ReadDirectoryChangesW 问题

c# - 使用 Control.Invoke 的死锁?

c# - 如何通过指定开始和结束索引从字典中获取一系列项目

c# - 将 lambda 重构为事件方法

c# - 如何在 Web Api 中使用 Api key 使用表单例份验证进行服务身份验证

c# - 如何用正则表达式中的特定符号替换特殊字符和空格?

objective-c - Objective-C 中的异步调用

c# - 为什么这段代码是同步运行的?

c# - 异步/等待 : Unexpected behaviour of ConfigureAwait