Windows窗体:有没有办法等待所有未决调用到控制结束?窗体、没有办法、结束、Windows

2023-09-07 09:20:45 作者:醉在现实,醒在梦里

我需要这样做,以解决死锁。 我的Windows窗体控件的引用,它封装一个C ++本机类C ++ / CLI类。本机类使得回调到C ++ / CLI类,它们映射到由表单处理的事件。这些回调被称为从它运行所有的时间一个线程。

I need to do this in order to solve a deadlock. My Windows Forms Control has a reference to a C++/CLI class which wraps a C++ native class. The native class makes callbacks to the C++/CLI class, which maps them to events handled by the form. These callbacks are called from a thread which runs all the time.

当我要处理的控制,我注销所有的事件,使本机类不能再打了。一旦这样做了,我处置C ++ / CLI的包装,从而破坏了原生类。在本机类的析构函数,I信号线程终止使用Windows事件,并无限期地等待线程结束。

When I want to dispose the control, I unregister all events, so that the native class can't call back anymore. Once that's done, I dispose the C++/CLI wrapper, which in turn destroys the native class. In the native class destructor, I signal the thread to end using a Windows event, and wait indefinitely for the thread to end.

但是,如果线程在回调的中间处置启动时,他可能会在 Control.Invoke ,和死锁停止随之而来。因此,标题的问题。这可能吗?如果是这样,我可以继续这样的:

However, if the thread was in the middle of a callback when the disposal starts, he might be stopped in a Control.Invoke, and deadlock ensues. Hence the title question. Is this possible? If it were so, I could proceed this way:

注销所有事件(本地线程将不能再打了) 在等待所有未决.Invokes完成 在处置C ++ / CLI包装 在消灭C ++的本机类 信号线程终止 在等待线程结束 Unregister all events (native thread won't be able to call back anymore) Wait for all pending .Invokes to finish Dispose C++/CLI wrapper Destroy C++ native class Signal thread to end Wait for thread to end (can't deadlock with an Invoke since all of those finished and no more of them could have been fired since events were unregistered)

我接受其他的建议解决这个问题

I'm open to other suggestions for solving this problem

推荐答案

有回应的形式关闭事件,等待线程完成的可能性。这里有一个无法解决的线程竞争条件。和非常好的赔率僵局,的DoEvents将打破,但太丑陋了。

There is no possibility of responding to the form closing event and wait for the thread to finish. There's an unsolvable threading race condition. And very good odds for deadlock, DoEvents would break it but is too ugly.

实施的FormClosing事件,并告诉类停止​​运行的线程。而取消关闭的。螺纹应引发事件退出之前。使用的BeginInvoke()在事件处理程序封送调用主线程。

Implement the FormClosing event and tell the class to stop running its thread. And cancel the close. The thread should raise an event just before it exits. Use BeginInvoke() in the event handler to marshal that call to the main thread.

现在你有所有调用完成,因为他们是有序的保障。此外,你有一个保证线程不再产生任何更多的活动所以没有更多的调用来了,它是安全的退订事件(实际上没有必要)。设置一个标志,一个真正的接近,现在可以和调用close(),以实际关闭的形式。

Now you have a guarantee that all invokes are completed since they are ordered. Furthermore, you have a guarantee that the thread can no longer generate any more events so no more invokes are coming and it is safe to unsubscribe the events (not actually necessary). Set a flag that a real close is now possible and call Close() to actually close the form.