在我的主窗口(线程 A)中,我启动了一个新线程(线程 B),该线程在用户等待时执行一些工作。
如果出现错误或需要用户提供额外信息,线程 B 会触发事件,线程 A 将监听这些事件。
在线程 A 的事件监听器中,我需要向用户显示对话框消息,我有一个自定义对话框窗口并使用 dialogWindow.showDialog()
显示它。这工作正常,但是当我尝试设置对话框的所有者时会导致错误,我这样做 dialogWindow.Owner = Window.GetWindow(this)
。
我得到的错误是:调用线程无法访问此对象,因为另一个线程拥有它。
监听从不同线程触发的事件的正确方法是什么?
最佳答案
事件监听器代码将在触发事件的线程中隐式运行,因此事件监听器不是线程绑定(bind)的。
如果您想在 UI 中显示一些事件处理的结果,您应该自己进行编码。类似的东西:
void OnEvent(object sender, EventArgs args)
{
// runs in the event sender's thread
string x = ComputeChanges(args);
Dispatcher.BeginInvoke((Action)(
() => UpdateUI(x)
));
}
void UpdateUI(string x)
{
// runs in the UI thread
control.Content = x;
// - or -
new DialogWindow() { Content = x, Owner = this }.ShowDialog();
// - or whatever
}
因此:您最好在后台线程中执行您的计算(如果有的话),而无需触及 UI;之后,当您知道 UI 中需要更改哪些内容时,您可以在 UI 线程中执行 UI 更新代码。
Dispatcher
是控件的一个属性,因此如果您的代码是 UI 的一部分,您将免费获得 Dispatcher。否则,您可以从任何控件中获取调度程序(例如,control.Dispatcher
)。
关于c# - 来自不同线程的触发事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10315370/