首页 > 解决方案 > UI线程阻止DLL线程运行

问题描述

我有一个调用 C DLL 的 C# 应用程序。DLL 使用 CreateThread(...,THREAD_PRIORITY_TIME_CRITICAL) 创建一个时间关键的线程。DLL 被传递给回调的委托,以通知应用程序的通信状态。在 UI 开始运行之前一切正常,例如鼠标单击事件处理程序。只要 UI 事件处理程序正在运行,DLL 线程就会停止并仅在事件处理程序退出后恢复。代码摘录如下。

调用 SetCallback() 将回调函数设置为 DllSetStatus(),它将一些值打印到 RichTextBox "criticalRtb"

DllSetStatus() 可以从 DLL 线程调用或响应来自 C# 应用程序的调用(即 PrintToRTB() 可以从 DLL 线程调用或响应对 DLL_GetStatus() 的调用,如下所示)

一旦进入任何托管代码事件处理程序,如果 DllSetStatus() 正在从 DLL 线程执行,它将停止执行,直到 UI 线程退出。

有没有办法让 DLL 线程在 UI 中继续执行?

我尝试过的事情:

DLL代码如下:

typedef void(__stdcall * CsSetStatusFunc)(int);
CsSetStatusFunc PrintToRTB = (CsSetStatusFunc)0;
DllExport int __cdecl DLL_SetCallback(CsSetStatusFunc funcPtr)
{
    PrintToRTB = funcPtr;
    return(0);
}

DllExport int __cdecl DLL_GetStatus(void)
{
    PrintToRTB(currStatus);
    return(0);
}

static DWORD WINAPI threadComm(void* param)
{
    (void)param;
    for (;;) 
    {
        portRead();
        if (currStatus != lastStatus)
        {
            PrintToRTB(currStatus);
            lastStatus = currStatus;
        }
        Sleep(0);
    }
    return(0);
}

标签: c#multithreading

解决方案


由于调用 Invoke,似乎在 App 消息队列中发布消息的 DLL 回调被 UI 事件产生的任何 UI 消息阻止,因此如果在任何 UI 事件消息之后发布 Invoke 消息,它将不会执行直到首先处理 UI 事件。如果 Invoke 消息处于挂起状态,我目前正在使用 DoEvents() 来使用队列中的消息。


推荐阅读