C# 进度条在完成一半进度之前不会更新

本文关键字:更新 一半 | 更新日期: 2023-09-27 18:19:19

我正在使用dispatcherTimer来更新进度条的值:

DispatcherTimer tim = new DispatcherTimer();
tim.Interval = TimeSpan.FromMilliseconds(100);
tim.Tick += delegate
{
    if (valuee < max)
    {
        prog.Value = valuee;
    }
    else
    {
        tim.Stop();
    }
};

并像这样设置进度条的最大值:

using (FileStream fs = File.Open(Filename, FileMode.Open))
{
    if (fs.Length > 10485760 && fs.Length <= 209715200)
        prog.Maximum = fs.Length / 1024;
    else if (fs.Length <= 10485760)
        prog.Maximum = fs.Length / 16;
    else if(fs.Length > 209715200)
        prog.Maximum = fs.Length / 1048576;
}

然后在 for 循环的每次迭代后增加该值:

var Input = File.OpenRead(path);
int Size = MainWindow.prog.Maximum;
for (long i = 0; i < Input.Length; i += Size)
{
    MainWindow.valuee++;
    PasswordEnter.valuee++;
    byte[] chunkData = new byte[chunkSize];
    int bytesRead = 0;
    while ((bytesRead = fsInput.Read(chunkData, 0, chunkSize)) > 0)
    {
        if (bytesRead != chunkSize)
        {
            for (int x = bytesRead - 1; x < chunkSize; x++)
            {
                chunkData[x] = 0;
            }
        }
        cryptoStream.Write(chunkData, 0, bytesRead);
    }
}

编辑:这就是我如何称呼AESCryptgraphy类:

BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += (obj, l) => lo.Encrypt(Filename, password.Password, "main");
worker.RunWorkerAsync();

但是由于某种原因,进度条直到超过一半的迭代结束才更新! 怎么了?

C# 进度条在完成一半进度之前不会更新

DispatcherTimer队列在Dispatcher线程(即 WPF UI 线程(上工作。

以下是 MSDN 关于计时器执行的说法:

调度程序

计时器在每个调度程序循环的顶部重新计算。 计时器不保证在时间间隔发生时准确执行,但保证它们不会在时间间隔发生之前执行。这是因为调度程序计时器操作与其他操作一样放置在调度程序队列中。调度程序计时器操作的执行时间取决于队列中的其他作业及其优先级。

遇到了进度计时器的滞后,因为您很可能正在运行一个长时间的阻塞操作,该操作拒绝处理不同请求的消息循环。

您有两种选择:

  1. 将长时间运行的操作移动到后台线程。我更喜欢这种方法。

  2. 尝试使用DispatcherTimer重载,它需要DispatcherPriority并指定更高的优先级。此方法仍不能保证您体验到性能变化,但可能会有所帮助。

循环代码打开一个文件,然后在for循环内递增进度 ( valuee (。似乎while循环读取到文件末尾。然后,for循环继续具有while以确保它仍然处于EOF,因为没有打开新文件。(我假设InputfsInput应该是同一个变量。

BackgroundWorker线程上的ReportProgress/ProgressChanged机制是处理从后台工作线程更新 UI 的跨线程复杂性的可靠方法。您可以使用UserState传递其他信息,例如当前正在处理以显示在标签中的文件的名称。