现在不幸的是,由于WinCE Usb设备到达/删除通过WindowsMessages暴露自己,我必须确保在后台线程上创建某个(非UI)组件不。我想通过异常断言,但缺少断言的代码。
此组件创建MessageWindow *并使用它来接收usb到达/删除的消息。问题是如果有人在后台线程上创建这个组件(不一定是; IsBackground = true),当线程退出窗口时将被销毁。
有什么想法吗?
*作为旁白,我仍然不知道为什么Form不会继承此类
更新
我认为我的第1版不太清楚。所以这是v2。
当在线程上为该事项创建MessageWindow或Form时,该线程退出Window / Form时将被销毁。
我的组件正在创建一个“隐藏”消息窗口来拦截一些重要事件,因为我不希望它被销毁。因此,我必须以某种方式确保创建表单的代码在“主UI”线程上运行。
如果可能的话,我希望避免将对“主”表单的引用传递给此组件,因为它(在架构上讲)应该离UI很远。
更新
将记录问题移至单独的Q.
答案 0 :(得分:1)
好的,我知道你不希望你的组件“知道”主窗口 - 这是有道理的。
怎么样:如果你确定你总是在主线程上实例化组件怎么样?你的组件将在构造函数的线程上创建它的监听器窗口。
如果你这样做,那么你只需要确保从主线程调用构造函数。我对你的代码做了一些假设,但我猜你必须在你的架构中有一些知道UI和组件的类。使用回调和主窗体的InvokeRequired / Invoke方法在那里创建组件。
答案 1 :(得分:0)
在表单中,您使用InvokeRequired属性。
答案 2 :(得分:0)
为什么不在后台线程上创建非UI组件,当你去更新任何UI组件时,只需查看invokeRequired然后返回主线程以实际进行更新。
你应该没有真正占用主要事件线程IMO。
答案 3 :(得分:0)
您可以这样使用它:
void MyCallback()
{
if (form1.InvokeRequired) { // form1 is any existing gui control
form1.Invoke(new Action<>(MyCallBack));
return;
}
// your logic here
}
答案 4 :(得分:0)
嘿那里:我对你的问题有所了解。这只是一个随意的想法,我不确定它是否会起作用(我没有测试过,甚至没有编译过 - 它只是打了我):
如果您获得应用程序主窗口的窗口句柄,然后围绕它构建一个控件(我假设您有一个基于gdi的应用程序,如Winforms),该怎么办?
这段代码可能无法编译,但它很接近(它会进入你的组件 - 注意它会使你的组件需要一个gdi windows / winform应用程序,而不是控制台或WPF应用程序。)
如果您尝试过,我很想知道它是否适合您。
using System.Diagnostics;
using System.Windows.Forms;
void Init()
{
// get handle to the main window
intPtr mainWindowHandle = Process.GetCurrentProcess().MainWindowHandle;
Control mainWindow = Control.FromHandle(mainWindowHandle);
if(mainWindow.InvokeRequired)
mainWindow.Invoke(SetupMessageWindow);
else
SetupMessageWindow();
}
void SetupMessageWindow()
{
// do your thing...
}