【发布时间】:2015-09-12 09:24:25
【问题描述】:
我想使用 VB.Net 在我的 UDP 多播接收器中实现超时。基本上,如果我在 10 秒内没有收到任何数据包,我想停止收听。我可以很容易地使用间隔为 10000 的Timer 来知道何时需要超时,但问题是如何停止接收功能?如果我使用Receive() 函数(阻止的函数),我可以简单地通过Thread.Abort() 调用来停止它。然而,我所阅读的所有内容都表明这不是一种安全的做法。如果我使用异步BeginReceive() 函数,我不知道如何在它正常完成之前终止它,因为如果没有使用从BeginReceive() 返回的IASyncResult 调用它,EndReceive() 将引发异常。
this question 的答案让我研究了CancelAsync() 方法。但是,this question 的回答让我很紧张。
如果我使用阻塞接收,我将无法连续轮询CancellationPending 属性,除非我从 DoWork 处理程序中在其自己的线程中调用Receive()。但这意味着它会在取消生效后继续运行,对吗?如果我使用BeginReceive(),我担心CancelAsync() 会被DoWork 处理程序“吃掉”,我最终会遇到同样的问题。
另外,BackgroundWorker 文档中的这个 sn-p 并不令人放心......
请注意,您在 DoWork 事件处理程序中的代码可能会在发出取消请求时完成其工作,并且您的轮询循环可能会错过将 CancellationPending 设置为 true 的情况。在这种情况下,您的 RunWorkerCompleted 事件处理程序中 System.ComponentModel.RunWorkerCompletedEventArgs 的 Canceled 标志不会设置为 true,即使已发出取消请求。
我想到的另一种选择是让发送数据包的UdpClient 负责超时,然后让它发送某种取消信号数据包以指示接收器应该停止侦听。这样做的问题是,鉴于 UDP 的性质,无法保证所述数据包会到达,或者以正确的顺序被提取。
有没有办法在 UDP 接收过程完成之前安全地终止它?
【问题讨论】:
标签: vb.net multithreading asynchronous timeout