你怎么知道你是否在主UI线程上? (在CF中)

时间:2009-05-05 15:17:22

标签: c# .net compact-framework

现在不幸的是,由于WinCE Usb设备到达/删除通过WindowsMessages暴露自己,我必须确保在后台线程上创建某个(非UI)组件。我想通过异常断言,但缺少断言的代码。

此组件创建MessageWindow *并使用它来接收usb到达/删除的消息。问题是如果有人在后台线程上创建这个组件(不一定是; IsBackground = true),当线程退出窗口时将被销毁。

有什么想法吗?

*作为旁白,我仍然不知道为什么Form不会继承此类

更新

我认为我的第1版不太清楚。所以这是v2。

当在线程上为该事项创建MessageWindow或Form时,该线程退出Window / Form时将被销毁。

我的组件正在创建一个“隐藏”消息窗口来拦截一些重要事件,因为我不希望它被销毁。因此,我必须以某种方式确保创建表单的代码在“主UI”线程上运行。

如果可能的话,我希望避免将对“主”表单的引用传递给此组件,因为它(在架构上讲)应该离UI很远。

更新

将记录问题移至单独的Q.

5 个答案:

答案 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...
}