C#中的跨线程事件处理
我正在使用一个框架,该框架在一个单独的线程中运行自己的事件调度程序。 框架可能会生成一些事件。
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;
-
现在, 这种方法是线程安全的吗? 如果表单处于关闭状态,而外部线程调用
BeginInvoke
,如果表单关闭,调用是否仍会排队等待执行? (这意味着我仍然有机会遇到同样的问题) -
是否有更好的方法或推荐的跨线程事件处理模式?
不它不是。 线程可能只是在您取消注册并关闭表单时执行事件处理程序。 赔率很小,但不是零。 在关闭表单之前必须先停止线程。 如果您不想中止它,则必须通过取消FormClosing事件来保持表单处于打开状态,然后让线程的完成回调关闭表单。
查看此主题以获取更多信息。
您可以将此代码添加到构造函数CheckForIllegalCrossThreadCalls = false;
并且不会抛出exception。
我没有使用具有自己的事件调度程序的框架,但我对自己创建的线程有自己的经验。 这是我的经历
-
这种方法不是线程安全的。 即使程序本身已关闭,仍将调用调用。 我在任务管理器中看到这个(在程序关闭后如你所说)作为挂线程。 (即使你也从任务管理器中杀了程序。) 我不得不单独杀死那些线程。
-
当表单关闭时,您必须终止调度程序线程,以便在该线程中发生任何错误时它不会挂起。
上述就是C#学习教程:C#中的跨线程事件处理分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
form.Closing += (sender, eargs) => src.OnFrameworkEvent -= form.SomeAction; // pseudo-code (find c# equivalent) if (dispatcherthread.isrunning) dispatcherThread.kill();
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1013629.html