winforms 使用不同线程的进度更新标签的正确方法

n53p2ov0  于 2022-11-17  发布在  其他
关注(0)|答案(1)|浏览(185)

我有一个windows窗体程序。在主窗体中,我有一个标签,我在其中更新进度。我使用以下代码来执行我的操作:

Thread workThread = new Thread(delegate ()
{
    for (int i = 1; i < bytes.Length; i++)
    {
        SliderOverBytesAndDoProcessing();
    }
});

workThread.Start();

函数SliderOverBytesAndDoProcessing()执行一些操作,我读取4个字节,并对更多字节执行一些操作。我对200 MB文件的每4个字节执行这些操作(读取4个字节,处理一些内容,然后继续移动)。在我决定报告我的进度之前,一切都运行正常。下面是我执行更新的方法:

Thread workThread = new Thread(delegate ()
{
    for (int i = 1; i < bytes.Length; i++)
    {
        Lbl.Invoke((Action)delegate { Lbl.Text = "Processing " + (ii / 1048576) + "/" + (bytes.Length / 1048576); }
        SliderOverBytesAndDoProcessing();
    }
});

workThread.Start();

如果我添加这一行,程序会变得太慢。我的意思是,没有这一行程序运行大约几分钟,但有了这一行,它需要大约1.5小时。而且,在其他一些操作中,如果我这样做,我最终会陷入无限循环。我如何从其他线程报告我的进度,以形成线程,而不面临这个问题。

  • 谢谢-谢谢
bwntbbo3

bwntbbo31#

它很慢,因为你要在每个字节上调度UI线程,即使进度消息似乎只关心兆字节。
考虑

var totalMb = bytes.Length / 1024 / 1024;
var lastMb = -1;

for (int i = 1; i < bytes.Length; i++) {
  var currentMb = i / 1024 / 1024;
  if (currentMb > lastMb) {
    Lbl.Invoke(() => { Lbl.Text = $"Processing {currentMb}/{totalMb} MiB" });
    lastMb = currentMb;
  }
  SliderOverBytesAndDoProcessing();
}

相关问题