我有这种形式,它产生一个新线程并开始在循环中侦听和等待 UDP 数据包。我需要的是使用接收到的字节数来更新 UI。
为此,我设置了一个事件,我将在收到数据包后立即引发,并将接收到的字节数作为参数传递。由于我没有在 UI 线程上运行,因此我不能简单地直接更新 UI。这是我目前正在做的事情:
private void EVENTHANDLER_UpdateTransferProgress(long receivedBytes) {
if(InvokeRequired) {
Invoke(new MethodInvoker(() => {
totalReceivedBytes += receivedBytes;
Label.Text = totalReceivedBytes.ToString("##,0");
}));
}
}
但这仍然与数据包接收循环在同一线程上运行,并且它不会返回到该循环 - 并等待另一个数据包 - 直到此EVENTHANDLER_UpdateTransferProgress
方法返回。
我的问题基本上是关于上述方法中的以下行:
Label.Text = totalReceivedBytes.ToString("##,0");
像这样更新 UI 会减慢数据包的接收速度。如果我把那条线去掉(或评论它),数据包接收会快得多。
我怎么可能解决这个问题?我认为更多线程是关键,但我不确定如何在这种情况下正确实现它们......我正在使用带有 .NET 2.0 的 Windows 窗体。
编辑:
在我之前的测试中,以上似乎是正确的,实际上可能在某种程度上是正确的。但经过更多测试后,我意识到问题出在整体上Invoke(new MethodInvoker(() => { ... }));
。当我删除它(当然 UI 不会更新)并离开EVENTHANDLER_UpdateTransferProgress
但继续引发事件时,数据包接收会快得多。
我测试了接收一些平均大约 1.5 秒的文件,而根本没有调用Invoke()
事件处理程序。当我确实调用Invoke()
事件处理程序时,即使没有更新 UI 中的任何控件或执行任何操作(换句话说,匿名方法体是空的),它也需要更长的时间,大约 5.5 秒。你可以看到这是一个很大的不同。
有没有办法改善这一点?