.net 你如何';取消';UdpClient::BeginReceive?
我有一个线程,它使用.net 你如何';取消';UdpClient::BeginReceive?,.net,asynchronous,c++-cli,udpclient,.net,Asynchronous,C++ Cli,Udpclient,我有一个线程,它使用UdpClient::BeginReceive等待来自多个接口的UDP消息,还有一个回调,调用UdpClient::EndReceive来提取数据并传递 如果5秒钟后我什么也没有得到,我将从调用UdpClient::BeginReceive的函数返回,以便取消该进程并发出另一个广播,该广播将触发外部客户端发送UDP响应。如果不取消,我将再次调用UdpClient::BeginReceive函数检查新数据 如果客户端没有及时接收到任何数据,是否有办法取消该异步请求而不调用End
UdpClient::BeginReceive
等待来自多个接口的UDP消息,还有一个回调,调用UdpClient::EndReceive
来提取数据并传递
如果5秒钟后我什么也没有得到,我将从调用UdpClient::BeginReceive
的函数返回,以便取消该进程并发出另一个广播,该广播将触发外部客户端发送UDP响应。如果不取消,我将再次调用UdpClient::BeginReceive
函数检查新数据
如果客户端没有及时接收到任何数据,是否有办法取消该异步请求而不调用
EndReceive
哪个模块会无限期阻塞?我得到的印象是,让数百个异步触发器运行是个坏主意。您需要拉动地板垫,调用UdpClient.Close()方法
这将完成BeginReceive()调用,您的回调方法将运行。当调用EndReceive()时,该类让您知道地板垫已消失,并将抛出ObjectDisposedException。因此,要准备好处理此异常,请使用try/catch包装EndReceive()调用,以便捕获ODE并退出回调方法
请注意,这往往会让.NET程序员感到不安,通常强烈不鼓励使用异常进行流控制。但是,您必须调用EndInvoke(),即使您已经知道这将引发异常。否则将导致持续一段时间的资源泄漏。对于取消
BeginRecieve
可以使用Close
方法,但在基本实现中,它将调用ObjectDisposedException
。我通过创建自定义BeginRecieve
修复了它,这是基本实现的现代化:
public Task<UdpReceiveResult> ReceiveAsync(UdpClient client, CancellationToken breakToken)
=> breakToken.IsCancellationRequested
? Task<UdpReceiveResult>.Run(() => new UdpReceiveResult())
: Task<UdpReceiveResult>.Factory.FromAsync(
(callback, state) => client.BeginReceive(callback, state),
(ar) =>
{
if (breakToken.IsCancellationRequested)
return new UdpReceiveResult();
IPEndPoint remoteEP = null;
var buffer = client.EndReceive(ar, ref remoteEP);
return new UdpReceiveResult(buffer, remoteEP);
},
null);
public Task ReceiveAsync(UdpClient客户端,CancellationToken-breakToken)
=>breakToken.IsCancellationRequested
? Task.Run(()=>newudpreciveresult())
:Task.Factory.fromsync(
(回调,状态)=>client.BeginReceive(回调,状态),
(ar)=>
{
if(breakToken.IsCancellationRequested)
返回新的UdpReceiveResult();
IPEndPoint remoteEP=null;
var buffer=client.EndReceive(ar,ref remoteEP);
返回新的UdpReceiveResult(缓冲区、remoteEP);
},
无效);
更多信息请阅读此处:
这也会对我有所帮助:。这几乎是我发帖后得出的结论。我的实现现在不是最干净的。实际上,我认为我应该让每个接口运行一个侦听器,并且只使用Close()关闭,正如您所建议的,当需要正确处理事情时。谢谢您的确认。欢迎访问SO。请添加更多信息此代码的作用以及解决问题的原因。
// Set ReadMsg = true while using UdpClient
// Set ReagMsg = false before Dispose or Close no Exception Error
private static bool ReadMsg;
private static void ReceiveCallback(IAsyncResult ar)
{
UdpClient u = (UdpClient)((UdpState)(ar.AsyncState)).u;
IPEndPoint e = (IPEndPoint)((UdpState)(ar.AsyncState)).e;
try
{
if ( ReadMsg )
{
Byte[] receiveBytes = u.EndReceive(ar, ref e);
string sddpMessage = Encoding.ASCII.GetString(receiveBytes);
}
}
catch (Exception ex)
{
Debug.WriteLine($"{ex.Message}");
}
}