在我的 WPF 应用程序中,我有一个长时间运行的上传运行,它会在运行时引发进度事件,从而更新进度条。用户也有机会取消上传,否则可能会出错。这些都是异步事件,因此需要使用 Dispatcher.Invoke 执行它们才能更新 UI。
所以代码看起来像这样,ish:
void OnCancelButtonClicked(object sender, EventArgs e)
{
upload.Cancel();
_cancelled = true;
view.Close();
view.Dispose();
}
void OnProgressReceived(object sender, EventArgs<double> e)
{
Dispatcher.Invoke(() =>
{
if (!cancelled)
view.Progress = e.Value;
}
}
假设在已处置视图上设置 view.Progress 会引发错误,那么这段代码线程安全吗?即如果用户在进度更新时单击取消,他/她将不得不等到进度更新,如果在执行 OnCancelButtonClicked 期间更新了进度,则 Dispatcher.Invoke 调用将导致 view.Progress 更新为在 _cancelled 设置后排队,所以我不会在那里遇到问题。
或者我是否需要一把锁才能安全,例如:
object myLock = new object();
void OnCancelButtonClicked(object sender, EventArgs e)
{
lock(myLock)
{
upload.Cancel();
_cancelled = true;
view.Close();
view.Dispose();
}
}
void OnProgressReceived(object sender, EventArgs<double> e)
{
Dispatcher.Invoke(() =>
{
lock(myLock)
{
if (!cancelled)
view.Progress = e.Value;
}
}
}