C# 使用后台线程时高效显示文件状态
如何在使用后台线程时有效地显示文件的状态 例如,假设我有一个100MB的文件: 当我通过一个线程执行下面的代码时(作为一个示例),它将在大约1分钟内运行: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 =
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,特别是当工作在另一个线程上完成时。