我正在使用C#编写WPF应用程序,我想实现第二个后台工作器对象。我已经有1个以我想要的方式工作。
第一个后台工作人员根据某些操作更新进度条。 我希望第二个更新显示倒数计时器的文本块。
首先,这可能吗? 目前,当计时器倒计时并达到零时,当另一个线程尝试访问进度条时,它会出错。
调用线程无法访问此对象,因为另一个线程拥有它。
以下是我的后台工作人员的代码: 在主窗口方法中,我初始化它们。
// Add the background worker events
worker.DoWork += worker_DoWork;
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
worker.ProgressChanged += worker_ProgressChanged;
worker.WorkerReportsProgress = true;
worker_timer.DoWork += worker_TrackTime;
worker_timer.RunWorkerCompleted += worker_TimeCompleted;
worker_timer.ProgressChanged += worker_timerProgressChanged;
worker_timer.WorkerReportsProgress = true;
以下是线程方法:
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
// Run all background tasks here
copyEverything(sourceFolder, targetFolder);
}
private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// Update UI once worker complete his work
// Update the progress bar and progress percent text to the max value it can be
copy_progressbar.Value = copy_progressbar.Maximum;
copy_textblock.Text = copy_progressbar.Maximum + "%";
worker.RunWorkerCompleted -= new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
worker.DoWork -= new DoWorkEventHandler(worker_DoWork);
}
void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// Update something here
copy_progressbar.Value = e.ProgressPercentage;
copy_textblock.Text = e.ProgressPercentage + "%";
// Check if the progressbar has reached its maximum value, if so set the value to its max
if (copy_progressbar.Value >= copy_progressbar.Maximum)
{
copy_progressbar.Value = copy_progressbar.Maximum;
copy_textblock.Text = copy_progressbar.Maximum + "%";
}
}
private void worker_TimeCompleted(object sender, RunWorkerCompletedEventArgs e)
{
}
private void worker_TrackTime(object sender, DoWorkEventArgs e)
{
while (true)
{
Thread.Sleep(1000);
elapsedTS = elapsedTS.Add(new TimeSpan(0, 0, 1));
try
{
worker_timer.ReportProgress(1);
}
catch
{
}
if (elapsedTS >= schedule.TS)
{
copyEverythingAsync(sourceFolder, targetFolder);
schedule.updateSchedule(DateTime.Now, false);
schedule.checkSchedule();
checkScheduleTime();
elapsedTS = TimeSpan.Zero;
}
}
}
private void worker_timerProgressChanged(object sender, ProgressChangedEventArgs e)
{
time_left_textblock.Text = "" + schedule.TS.Subtract(elapsedTS).ToString(@"dd\.hh\:mm\:ss");
//time_left_textblock.Text = "" + schedule.TS.Subtract(elapsedTS).ToString();
}
跟踪计时器的线程没有完整的方法,因为我希望它能够连续运行。
如果需要,我可以提供更多信息。
答案 0 :(得分:1)
您需要使用UI线程更新UI。
private void worker_timerProgressChanged(object sender, ProgressChangedEventArgs e)
{
Dispatcher.Invoke(() =>
{
time_left_textblock.Text = "" + schedule.TS.Subtract(elapsedTS).ToString(@"dd\.hh\:mm\:ss");
});
}