我有一个ProgressBarWindow,里面有一个进度条和一个取消按钮。它用于报告文件I/O的进度。然而,尽管所有的工作都在后台线程中完成,但ProgressBarWindow的UI线程和我的主窗口仍然会挂起。虽然后台线程在执行任务,但进度条以及主窗口并没有更新。以下代码是在主窗口构造函数末尾调用的:
这里是ProgressBarWindow的简化版本(其余部分仅包含几个setter):
我尝试将值设置行包装在dispatcher.invoke委托中,但这会导致堆栈溢出(我不应该有一个dispatcher.invoke行,因为backgroundworker在UI线程中调用ProgressChanged,对吗?)。我已经查阅了msdn和谷歌,但似乎没有其他人遇到过这个问题。
编辑:抱歉,我没有意识到我的简化代码会阻塞UI线程,尽管使用了backgroundworker,但我得到了完全相同的行为,因此错误地认为它们是等价的。我应该提到我正在使用backgroundworker :P
iCountLogLinesProgressBar = new ProgressBarWindow();
iCountLogLinesProgressBar.cancelButton.Click += EventCountLogLinesProgressBarCancelButtonClicked;
iCountLogLinesProgressBar.Show();
iCountLogRecords = new BackgroundWorker();
iCountLogRecords.DoWork += EventCountLogLinesDoWork;
iCountLogRecords.ProgressChanged += EventCountLogLinesProgressChanged;
iCountLogRecords.RunWorkerCompleted += EventCountLogLinesRunWorkerCompleted;
iCountLogRecords.WorkerReportsProgress = true;
iCountLogRecords.WorkerSupportsCancellation = true;
iCountLogRecords.RunWorkerAsync(new BinaryReader(File.Open(iMainLogFilename, FileMode.Open, FileAccess.Read)));
EventCountLogLinesProgressChanged() 的样子如下:
private void EventCountLogLinesProgressChanged(object sender, ProgressChangedEventArgs e)
{
iCountLogLinesProgressBar.Value = e.ProgressPercentage;
}
这里是ProgressBarWindow的简化版本(其余部分仅包含几个setter):
public partial class ProgressBarWindow : Window
{
public ProgressBarWindow()
{
InitializeComponent();
this.progressBar.Value = this.progressBar.Minimum = 0;
this.progressBar.Maximum = 100;
}
public double Value
{
get
{
return progressBar.Value;
}
set
{
this.progressBar.Value = value;
}
}
}
我尝试将值设置行包装在dispatcher.invoke委托中,但这会导致堆栈溢出(我不应该有一个dispatcher.invoke行,因为backgroundworker在UI线程中调用ProgressChanged,对吗?)。我已经查阅了msdn和谷歌,但似乎没有其他人遇到过这个问题。
编辑:抱歉,我没有意识到我的简化代码会阻塞UI线程,尽管使用了backgroundworker,但我得到了完全相同的行为,因此错误地认为它们是等价的。我应该提到我正在使用backgroundworker :P