我正在使用一个框架,该框架在单独的线程中运行自己的事件调度程序。该框架可能会生成一些事件。
class SomeDataSource {
public event OnFrameworkEvent;
void FrameworkCallback() {
// This function runs on framework's thread.
if (OnFrameworkEvent != null)
OnFrameworkEvent(args);
}
}
我想将这些事件传递给 Winforms 线程上的 Winforms 对象。我显然检查InvokeRequired
如有必要,将其分派给 Winforms 线程。
class SomeForm : Form {
// ...
public void SomeAction(SomeArgs args) {
if (InvokeRequired) {
BeginInvoke(new Action(SomeAction), args);
return;
}
// ...
}
}
现在,当表单正在关闭的过程中可能会传递事件,这会导致各种各样的问题,因此我从 Winforms 线程上的框架事件源中取消注册表单的事件处理程序,如下所示:
var form = new SomeForm();
var src = new SomeDataSource();
// ...
src.OnFrameworkEvent += form.SomeAction;
form.Closing += (sender, eargs) => src.OnFrameworkEvent -= form.SomeAction;
Now, 这种方法是线程安全的吗?如果表单正在关闭过程中,并且外部线程调用BeginInvoke
,如果表单关闭,调用是否仍会排队等待执行? (这意味着我仍然有机会遇到同样的问题)
是否有更好的方法或推荐模式来处理跨线程事件?
不它不是。当您取消注册线程并关闭表单时,该线程可能只是在执行事件处理程序。几率很小,但不是零。您必须先停止线程,然后才能关闭表单。如果您不想中止它,则必须通过取消 FormClosing 事件来保持表单打开,然后让线程的完成回调关闭表单。
Check 这个线程 https://stackoverflow.com/questions/1731384/how-to-stop-backgroundworker-on-forms-closing-event了解更多信息。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)