C# C语言中的跨线程事件处理#
我使用的框架在单独的线程中运行自己的事件调度器。框架可能会生成一些事件C# C语言中的跨线程事件处理#,c#,winforms,multithreading,event-handling,C#,Winforms,Multithreading,Event Handling,我使用的框架在单独的线程中运行自己的事件调度器。框架可能会生成一些事件 class SomeDataSource { public event OnFrameworkEvent; void FrameworkCallback() { // This function runs on framework's thread. if (OnFrameworkEvent != null) OnFrameworkEvent(a
class SomeDataSource {
public event OnFrameworkEvent;
void FrameworkCallback() {
// This function runs on framework's thread.
if (OnFrameworkEvent != null)
OnFrameworkEvent(args);
}
}
我想将这些事件传递到Winforms线程上的Winforms对象。我显然会检查invokererequired
,并在必要时将其发送到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
,那么如果表单关闭,调用是否仍会排队等待执行?(这意味着我仍然有机会遇到同样的问题)我没有将框架与自己的事件调度器一起使用,但我有自己创建线程的经验。这是我的经验
form.Closing += (sender, eargs) => src.OnFrameworkEvent -= form.SomeAction;
// pseudo-code (find c# equivalent)
if (dispatcherthread.isrunning)
dispatcherThread.kill();
不,不是。当您注销事件处理程序并关闭表单时,线程可能正在执行该事件处理程序。几率很小,但不是零。必须先停止线程,然后才能关闭窗体。如果不想中止,则必须通过取消FormClosing事件来保持窗体打开,然后让线程的完成回调关闭窗体
查看更多信息。您可以将此代码添加到构造函数
CheckForIllegalCrossThreadCalls=false代码>将不会引发异常。如果调度程序线程需要保持活动状态以处理其他Winforms,该怎么办?恐怕就是这样。我有多个窗体侦听同一事件源。如果我正确理解您的意思,那么将线程的IsBackground属性设置为true将防止挂起线程。我喜欢这种方法。我喜欢使用回调方法在线程完成时发出信号。