gpt4 book ai didi

c# - 如何在 C# 中传输数据包时正确保持 UI 更新?

转载 作者:行者123 更新时间:2023-11-30 21:07:50 26 4
gpt4 key购买 nike

我有一个生成新线程并开始监听并循环等待 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 会减慢数据包接收速度。如果我取消那条线(或评论它),数据包接收会快得多。

我怎样才能解决这个问题?我认为更多线程是关键,但我不确定在这种情况下如何正确实现它们...我正在使用 Windows Forms 和 .NET 2.0。

编辑:

根据我之前的测试,以上内容似乎是正确的,而且在某种程度上可能确实如此。但经过更多测试后,我意识到问题出在整个 Invoke(new MethodInvoker(() => { ... })); 事情上。当我删除它(UI 当然不会更新)并保留 EVENTHANDLER_UpdateTransferProgress 但继续引发事件时,数据包接收速度更快。

我测试了接收一些平均需要约 1.5 秒的文件,而根本没有在事件处理程序上调用 Invoke()。当我在事件处理程序中调用 Invoke() 时,即使没有更新 UI 中的任何控件或进行任何操作(换句话说,匿名方法主体为空),它也花费了更长的时间,大约~5.5 秒。您会发现这是一个很大的不同。

有什么可以改进的吗?

最佳答案

您的方法的问题在于它会在每个数据包上更新 UI。如果你每秒收到 1000 个数据包,你将每秒更新 UI 1000 次!监视器可能不会每秒刷新超过 100 次,如果每秒更新超过 10 次,则没有人能够读取它。

解决此问题的更好方法是将 totalReceivedBytes += receivedBytes; 放在处理 I/O 的线程中,并在执行 Label 的 UI 线程中放置一个计时器。 Text = totalReceivedBytes.ToString("##,0"); 最多每秒几次。当传输开始时,启动定时器;当传输停止时,停止计时器。

关于c# - 如何在 C# 中传输数据包时正确保持 UI 更新?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10066884/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com