我想了解我的UdpClient收到数据时是否可以通过某种方式触发事件?(System.Net.Sockets.UdpClient)
我尝试覆盖它的UdpClient.Receive,但是我不能按照此方法进行,因为可覆盖成员必须标记为虚拟或抽象。
我目前的方式是在特定时间间隔上在Threading.Timer上运行TimerCallback来获取我的数据,但我更希望在数据到达时接收传入数据,而不是重复获取数据。
关于如何执行此操作或需要定期手动接收的任何建议,建议或指示?
提前致谢。
Receive
无论如何,重写该方法将无济于事-当UDP客户端接收数据时,不会调用该方法,而当您要等待传入数据时,则调用该方法。
但是,该Receive
方法会阻塞。这意味着您实际上不必定期检查-您可以简单地(几乎)无限循环地检查。只需在其他线程中执行即可。
void Loop(CancellationToken token) { var remoteEP = default(IPEndPoint); while (!token.IsCancellationRequested) { var data = client.Receive(ref remoteEP); yourForm.Invoke(DataReceived, data); } }
当然,由于这是简单的I / O,因此不需要占用线程即可-您可以使用异步I / O:
public Task Loop(CancellationToken token) { using (UdpClient client = new UdpClient(80)) { while (!token.IsCancellationRequested) { var data = await client.ReceiveAsync(); // Process the data as needed } } }
在Winforms或WPF应用程序中,这几乎可以自动完成-您只需在btnStart_Click
事件处理程序中使用此代码,即可在等待后台数据时保持UI响应;并且每当数据返回时,它将Process the data as needed
在UI线程上执行其余代码()-无需手动创建任何线程或处理分派。
当然,处理终止有些棘手,但是对于UDP来说总是棘手-基本上,您要么必须使用支持取消的更手动的方式(ReceiveAsync
只是包装器,BeginReceive
并且EndReceive
不支持取消),或者将使用设置取消令牌的旧技巧,然后向自己发送一个长度为0的数据包(导致Receive
调用结束并返回零长度的字节数组)。