代码之家  ›  专栏  ›  技术社区  ›  Quibblesome

如何判断您是否在主UI线程上?(在CF中)

  •  1
  • Quibblesome  · 技术社区  · 15 年前

    现在不幸的是,由于WinCE USB设备的到达/移除通过WindowsMessages公开,我必须确保某个(非UI)组件 在后台线程上创建。我想通过一个异常来断言这一点,但是缺少断言的代码。

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

    有什么想法吗?

    作为旁白我 仍然 不知道为什么窗体不从此类继承

    更新

    我觉得我的版本1不太清楚。所以这是V2。

    当您在线程上为该事项创建一个messagewindow或表单时,当该线程退出时,该窗口/表单将被销毁。

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

    如果可能的话,我希望避免将对“主”窗体的引用传递给这个组件,因为它(从架构上讲)应该离UI有几英里远。

    更新

    将日志问题移动到单独的Q。

    5 回复  |  直到 15 年前
        1
  •  1
  •   JMarsch    15 年前

    好的,我理解您不希望组件“知道”主窗口——这是有意义的。

    这个怎么样:如果您确保总是在主线程上实例您的组件,那该怎么办?组件将在构造函数的线程上创建它的侦听器窗口。

    如果这样做,那么只需确保从主线程调用构造函数。我对您的代码做了一些假设,但我猜想您的体系结构中必须有一些既了解UI又了解组件的类。使用回调和主窗体的invokeRequired/invoke方法在那里创建组件。

        2
  •  0
  •   Tom Ritter    15 年前

    在窗体中,使用 InvokeRequired 财产。

        3
  •  0
  •   James Black    15 年前

    为什么不在后台线程上创建非UI组件呢?当您要更新任何UI组件时,只需查看是否需要调用,然后返回主线程来实际执行更新。

    在我看来,你不应该把主要事件的线索搞得一团糟。

        4
  •  0
  •   Stormenet    15 年前

    您可以这样使用它:

    void MyCallback()
    {
    if (form1.InvokeRequired) { // form1 is any existing gui control
        form1.Invoke(new Action<>(MyCallBack));
        return;
    }
    // your logic here
    }
    
        5
  •  0
  •   JMarsch    15 年前

    嘿,我对你的问题有个想法。这只是一个随机的想法,我不知道它是否会起作用(我没有测试过,甚至没有编译过这个——它只是击中了我):

    如果你得到了你的应用程序主窗口的窗口句柄,然后围绕它构建一个控件(我假设你有一个基于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...
    }