C#progressBar直到完成一半进度才更新

时间:2014-08-25 17:14:12

标签: c# .net wpf progress-bar dispatchertimer

我正在使用dispatcherTimer更新progressBar的值:

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

并设置progressBar的最大值,如下所示:

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);
    }
}

编辑:这就是我调用AESCryptography类的方式:

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

但由于某种原因,progressBar不会更新,直到超过一半的迭代结束!什么错了?

2 个答案:

答案 0 :(得分:2)

DispatcherTimer个队列在Dispatcher线程上工作,这是WPF UI线程。

这就是MSDN关于计时器执行的说法:

  

DispatcherTimer在每个Dispatcher循环的顶部重新评估。   不保证定时器在时间间隔发生时准确执行,但保证在时间间隔发生之前不执行定时器。这是因为DispatcherTimer操作与其他操作一样放在Dispatcher队列中。 DispatcherTimer操作执行时依赖于队列中的其他作业及其优先级。

您在进度计时器中遇到延迟,因为您很可能运行长阻塞操作,该操作拒绝处理不同请求的消息循环。

您有两种选择:

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

  2. 尝试使用DispatcherTimer overload DispatcherPriority并指定更高的优先级。这种方法仍然不能保证你会遇到性能变化,但它可能有所帮助。

答案 1 :(得分:1)

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

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