我有下面的代码,它可以从后台线程更新我的进度条和状态栏。我运行相同的后台线程两次。第一次我从MainWindow的构造函数中调用它,这样它就可以正常工作。在构造函数的末尾,我设置了一个定时器来每隔一段时间调用该方法。
这个解决方案虽然可行,但我认为BackgroundWorker的整个意义在于不需要这样做。有人可以解释一下我的错误假设以及实际情况吗?是否有一种方式可以通过设置计时器来避免使用调度程序?谢谢,Harrison。
System.Threading.TimerCallback timerCallback = new System.Threading.TimerCallback(RefreshWebDataTimer);
timer = new System.Threading.Timer(
timerCallback, null,
Dictionary.MS_TIMER_FIRSTREFRESH_PERIOD,
Dictionary.MS_TIMER_REFRESH_PERIOD);
当我从计时器中调用它时,我会得到以下错误:
第一次出现了“System.InvalidOperationException”类型的异常,源自WindowsBase.dll。附加信息:由于不同的线程拥有它,所以调用线程无法访问此对象。
我添加了一些调试代码,确实发现Dispatcher线程在与计时器不同的线程上,但与原始运行的线程相同。
private void backgroundWorker_ProgressChanged(object sender,
ProgressChangedEventArgs e)
{
System.Diagnostics.Debug.Print("Current Thread: {0}", System.Threading.Thread.CurrentThread.ManagedThreadId);
System.Diagnostics.Debug.Print("Dispatcher Thread: {0}", progressBar.Dispatcher.Thread.ManagedThreadId);
this.progressBar.Visibility = Visibility.Visible;
this.progressBar.Value = e.ProgressPercentage;
if (e.UserState != null)
{
this.statusBar.Text = e.UserState.ToString();
}
}
当前线程:22 调度器线程:7
我曾经以为ProgressChanged
和RunWorkerCompleted
事件总是在主UI线程上运行,以解决这个问题并能够进行UI更新。显然,我误解了这里发生的事情。
我更新了我的解决方案,如下所示:
private void backgroundWorker_ProgressChanged(object sender,
ProgressChangedEventArgs e)
{
progressBar.Dispatcher.BeginInvoke(new OneArgIntDelegate(updateProgressBar), e.ProgressPercentage);
if (e.UserState != null)
{
progressBar.Dispatcher.BeginInvoke(new OneArgStrDelegate(updateStatusBar), e.UserState.ToString());
}
}
private void updateStatusBar(string Text)
{
this.statusBar.Text = Text;
}
private void updateProgressBar(int ProgressPercentage)
{
this.progressBar.Visibility = Visibility.Visible;
this.progressBar.Value = ProgressPercentage;
}
这个解决方案虽然可行,但我认为BackgroundWorker的整个意义在于不需要这样做。有人可以解释一下我的错误假设以及实际情况吗?是否有一种方式可以通过设置计时器来避免使用调度程序?谢谢,Harrison。