使用后台线程时有效显示文件状态

发布于 2024-09-01 12:41:06 字数 799 浏览 3 评论 0原文

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

例如,假设我有一个 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(...)
        }
}

How can i efficiently display the status of a file when using a background thread?

For instance, lets say i have a 100MB file:

when i do the code below via a thread (just as an example) it runs in about 1 min:

foreach(byte b in file.bytes)
{
   WriteByte(b, xxx);
}

But... if i want to update the user i have to use a delegate to update the UI from the main thread, the code below takes - FOREVER - literally i don't know how long im still waiting, ive created this post and its not even 30% done.

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(...)
        }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

呆橘 2024-09-08 12:41:06

不要在每个字节上更新 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);
}

Dont update the UI on every byte. only update it for every 100k or so.

Observe:

int total = file.length;
int current = 0;
foreach(byte b in file.bytes)
{
   current++;
   if (current % 100000 == 0)
   {
        UpdateCurrentFileStatus(current, total);
   }
   WriteByte(b, xxx);
}
岛歌少女 2024-09-08 12:41:06

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

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

You're updating the UI too frequently -- every byte in a 100MB file is going to result in 100 million UI updates (marshalling to the UI thread for each).

Break your updates up into percentages of the total file size, maybe 10% or even 5% increments. So if the file size was 100 bytes, update the UI at 10, 20, 30, etc.

梦言归人 2024-09-08 12:41:06

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

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

I recommend that you update according to elapsed time so that you have predictable update intervals regardless of file size or system load:

    DateTime start = DateTime.Now;
    foreach (byte b in file.bytes)
    {
        if ((DateTime.Now - start).TotalMilliseconds >= 200)
        {
            UpdateCurrentFileStatus(current, total);
            start = DateTime.Now;
        }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文