[英]Can you pass an UI object created in a BackgroundWorker thread to the main thread?
[英]How can you tell if you're on the Main UI thread? (In CF)
现在不幸的是,由于WinCE Usb设备到达/删除是通过WindowsMessages自身公开的,因此我必须确保未在后台线程上创建某个(非UI)组件。 我想通过异常来断言,但是缺少断言的代码。
该组件创建一个MessageWindow *,并使用它来接收USB到达/删除的消息。 问题是,如果有人在线程退出窗口时在后台线程上创建此组件(不一定; IsBackground = true),则会被破坏。
有任何想法吗?
*顺便说一句,我仍然不知道为什么Form不从此类继承
更新资料
我认为我的版本1不太清楚。 所以这是v2。
当您在线程上为此创建MessageWindow或Form时,该线程退出时,Window / Form被销毁。
我的组件正在创建一个“隐藏的”消息窗口以拦截一些重要事件,因此,我不希望它被破坏。 因此,我必须以某种方式确保创建表单的代码在“主UI”线程上运行。
如果可能的话,我想避免将此组件的“主要”形式的引用向下传递,因为它(从体系结构上来说)应该距离UI数英里。
更新资料
将记录问题移至单独的Q。
好的,我知道您不希望您的组件“了解”主窗口-很有道理。
怎么样:如果您确保始终在主线程上实例化组件,该怎么办? 您的组件将在构造函数的线程上创建它的侦听器窗口。
如果这样做,则只需要确保从主线程调用构造函数即可。 我正在对您的代码做一些假设,但是我猜想您的体系结构中必须有一些同时了解UI和组件的类。 使用回调和主窗体的InvokeRequired / Invoke方法在此处创建组件。
在表单中,您使用InvokeRequired属性。
为什么不在后台线程上创建非UI组件,而当您更新任何UI组件时,只需看看是否invoke invoked然后回到主线程上即可进行更新。
您应该没有真正占用主事件线程IMO的任何东西。
您可以通过以下方式使用它:
void MyCallback()
{
if (form1.InvokeRequired) { // form1 is any existing gui control
form1.Invoke(new Action<>(MyCallBack));
return;
}
// your logic here
}
嘿:我对您的问题有个想法。 这只是一个随机的想法,我不确定它是否会起作用(我没有测试过,甚至没有编译过它-只是打在我身上):
如果您获得了应用程序主窗口的窗口句柄,然后围绕它构建控件(我假设您有一个基于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...
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.