【问题标题】:WTL multithreading, multiple interfaces & librariesWTL 多线程、多接口和库
【发布时间】:2013-08-22 13:27:13
【问题描述】:

我有一个显示界面的主线程,在显示主界面之前从主线程创建的另一个线程中,我按顺序创建了两个其他窗口: 我创建了第一个窗口:

    CWarningDlg warnDlg;
    warnDlg.Create(NULL);
    warnDlg.ShowWindow(SW_SHOW);
    warnDlg.BringWindowToTop();
    CMessageLoop _Loop ;

    if(_MyAppModule.AddMessageLoop(&_Loop))
    {
        nRet = _Loop.Run();
        _MyAppModule.RemoveMessageLoop();
    }
    warnDlg.DestroyWindow();
    if (nRet == SOME_VALUE)
    {
       doSomethingElse();
    }

做点别的有:

 CActionDlg actDlg;
    actDlg.Create(NULL);
    actDlg.ShowWindow(SW_SHOW);
    actDlg.BringWindowToTop();
    CMessageLoop _Loop ;

    if(_MyAppModule.AddMessageLoop(&_Loop))
    {
        CreateAnObject(); //this also launches an object Specific Worker Thread
        nRet = _Loop.Run();
        _MyAppModule.RemoveMessageLoop();
    }

函数 CreateAnObject 从“ComplexObject.DLL”调用一些函数,这些函数创建一个复杂对象,该对象保存调用 CREATION 函数的线程的线程 ID,它使用 ::GetCurrentThreadId(); 获取它,同时创建这个复杂对象 GetCurrentThreadId () 返回 SECOND THREAD 的 ID,这是 GOOD。 现在,在我的 CActionDialog 中,我使用 ind ::SendMessage() 接收来自该对象的通知,SendMessage 函数是从特定于刚刚创建的复杂对象的工作线程内调用的。 当我收到这些通知时,我需要访问一些复杂的对象值,为此我从“ComplexObject.DLL”调用其他一些函数,这些函数使用 ::GetCurrentThreadId() 函数验证调用线程的 ID 是否与创建该复杂对象的线程的 ID。该验证对我来说失败了,因为使用具有主界面 GUI 的主线程的线程 ID 调用了这些函数。 这是为什么?我不明白! (我希望我成功地解释了自己)。

【问题讨论】:

    标签: winapi visual-c++ wtl


    【解决方案1】:

    至少从您的描述来看,您似乎遇到的问题是,无论您通过 CreateAnObject 使用什么外部 API,它都将其进一步用于创建线程。照原样处理,您只能从创建线程进行调用。每当您在其他线程上运行的代码(包括托管CWarningDlg 的线程)需要与此API 通信时,您需要将调用转移到CActionDlg 线程并从那里继续。

    同步可以是 SendMessage 你已经做的,或者像 PostMessage 这样更安全的,带有事件/消息完成通知。

    【讨论】:

    • 但是 CActionDialog 在第二个线程中运行还不够吗?它是 CreateAnObject 函数的本地函数,我从那里创建该外部对象。不运行循环并在该线程中实例化 CActionDialog 是否意味着我正在从该线程运行?
    • SendMessage 通过魔法将调用“转移”到创建窗口的线程。如果您直接从那里使用指针,那将是另一个线程。我想这是让你感到困惑的部分。一旦切换到另一个线程,您并没有切换回来然后遇到线程不匹配。
    • 不是从复杂对象创建线程中的 _Loop.Run() 调用 DispatchMessage 吗?
    • 您写道,您看到主线程在运行,并且您看到 ID 不匹配。你应该能够从那里检查调用堆栈,看看你在哪里,尤其是。您当前正在处理什么消息。这将是一个主线程窗口,而不是CActionDlg
    • 线程 ID 不应该是线程 2 的 ID 吗? CMessageLoop 是否通过调用 ::DispatchMessage 来改变它?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-12
    • 1970-01-01
    • 2013-01-07
    • 2023-04-09
    • 2019-04-13
    • 2013-07-26
    • 1970-01-01
    相关资源
    最近更新 更多