我正在使用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不会更新,直到超过一半的迭代结束!什么错了?
答案 0 :(得分:2)
DispatcherTimer
个队列在Dispatcher
线程上工作,这是WPF UI线程。
这就是MSDN关于计时器执行的说法:
DispatcherTimer在每个Dispatcher循环的顶部重新评估。 不保证定时器在时间间隔发生时准确执行,但保证在时间间隔发生之前不执行定时器。这是因为DispatcherTimer操作与其他操作一样放在Dispatcher队列中。 DispatcherTimer操作执行时依赖于队列中的其他作业及其优先级。
您在进度计时器中遇到延迟,因为您很可能运行长阻塞操作,该操作拒绝处理不同请求的消息循环。
您有两种选择:
将长时间运行的操作移动到后台线程。我更喜欢这种方法。
尝试使用DispatcherTimer
overload DispatcherPriority
并指定更高的优先级。这种方法仍然不能保证你会遇到性能变化,但它可能有所帮助。
答案 1 :(得分:1)
循环代码打开一个文件,然后在for
循环内增加进度(valuee
)。似乎while
循环读取到文件结尾。然后for
循环保持while
确保它仍然处于EOF,因为没有打开新文件。 (我假设Input
和fsInput
应该是同一个变量。)
ReportProgress
线程上的ProgressChanged
/ BackgroundWorker
机制是处理从后台工作线程更新UI的跨线程复杂性的可靠方法。您可以使用UserState
传递其他信息,例如当前正在处理以在标签中显示的文件的名称。