C# 使用后台线程时高效显示文件状态

C# 使用后台线程时高效显示文件状态,c#,multithreading,statusbar,C#,Multithreading,Statusbar,如何在使用后台线程时有效地显示文件的状态 例如,假设我有一个100MB的文件: 当我通过一个线程执行下面的代码时(作为一个示例),它将在大约1分钟内运行: foreach(byte b in file.bytes) { WriteByte(b, xxx); } 但是。。。如果我想更新用户,我必须使用一个委托从主线程更新UI,下面的代码需要-永远-字面上我不知道我还要等多久,我创建了这篇文章,它甚至没有完成30% int total = file.length; int current =

如何在使用后台线程时有效地显示文件的状态

例如,假设我有一个100MB的文件:

当我通过一个线程执行下面的代码时(作为一个示例),它将在大约1分钟内运行:

foreach(byte b in file.bytes)
{
   WriteByte(b, xxx);
}
但是。。。如果我想更新用户,我必须使用一个委托从主线程更新UI,下面的代码需要-永远-字面上我不知道我还要等多久,我创建了这篇文章,它甚至没有完成30%

int total = file.length;
int current = 0;
foreach(byte b in file.bytes)
{
   current++;
   UpdateCurrentFileStatus(current, total);
   WriteByte(b, xxx);
}

public delegate void UpdateCurrentFileStatus(int cur, int total);
public void UpdateCurrentFileStatus(int cur, int total)
{
        // Check if invoke required, if so create instance of delegate
        // the update the UI

        if(this.InvokeRequired)
        {

        }
        else
        {
          UpdateUI(...)
        }
}

不要在每个字节上更新UI。仅每100k左右更新一次

注意:

int total = file.length;
int current = 0;
foreach(byte b in file.bytes)
{
   current++;
   if (current % 100000 == 0)
   {
        UpdateCurrentFileStatus(current, total);
   }
   WriteByte(b, xxx);
}

不要在每个字节上更新UI。仅每100k左右更新一次

注意:

int total = file.length;
int current = 0;
foreach(byte b in file.bytes)
{
   current++;
   if (current % 100000 == 0)
   {
        UpdateCurrentFileStatus(current, total);
   }
   WriteByte(b, xxx);
}

您更新UI的频率太高了——一个100MB文件中的每个字节都会导致1亿次UI更新(每个字节都会编组到UI线程)


将您的更新分为总文件大小的百分比,可能是10%甚至5%的增量。因此,如果文件大小为100字节,请在10、20、30等位置更新UI。

您更新UI的频率太高了——100MB文件中的每个字节都会导致1亿次UI更新(每个字节都会编组到UI线程)


将您的更新分为总文件大小的百分比,可能是10%甚至5%的增量。因此,如果文件大小为100字节,请在10、20、30等位置更新UI。

我建议您根据经过的时间进行更新,以便无论文件大小或系统负载如何,都有可预测的更新间隔:

    DateTime start = DateTime.Now;
    foreach (byte b in file.bytes)
    {
        if ((DateTime.Now - start).TotalMilliseconds >= 200)
        {
            UpdateCurrentFileStatus(current, total);
            start = DateTime.Now;
        }
    }

我建议您根据经过的时间进行更新,这样无论文件大小或系统负载如何,您都有可预测的更新间隔:

    DateTime start = DateTime.Now;
    foreach (byte b in file.bytes)
    {
        if ((DateTime.Now - start).TotalMilliseconds >= 200)
        {
            UpdateCurrentFileStatus(current, total);
            start = DateTime.Now;
        }
    }

非常奇怪,我在想,在我回到这一页之前,我会试一试,看看…我的意思是,即使是每1k字节…也要使用
控件。BeginInvoke
而不是
Invoke
,因此工作线程不必等待UI线程。非常奇怪,我一直在想,在我回到这一页之前,我会试一试,看看……我的意思是,即使每1k字节……也要使用
控件。BeginInvoke
而不是
Invoke
,这样工作线程就不必等待UI线程。对于循环中的相对时间测量,最好使用
秒表
甚至
DateTime.UtcNow
,这两种方法都比
DateTime快得多。现在
。很好。我也没有意识到DateTime.UtcNow更快(没有时区转换)。从回答其他问题中学习总是一种享受!您还可以使用System.Timer来更新UI,特别是当工作在另一个线程上完成时。对于循环中的相对时间测量,最好使用
秒表
,甚至
DateTime.UtcNow
,这两种方法都比
DateTime快得多。现在
。很好。我也没有意识到DateTime.UtcNow更快(没有时区转换)。从回答其他问题中学习总是一种享受!您还可以使用System.Timer来更新UI,特别是当工作在另一个线程上完成时。