我正在编写一个小测试应用程序来测试通信接口。通信接口用C ++(DLL)编写,测试应用程序用C#编写。通信接口又与低级硬件堆栈通信,后者使用Windows消息来发送和接收数据。为了实现这一点,通信接口DLL创建了一个不可见的子窗口,其父级是C#测试应用程序窗口。与硬件通信的顺序如下:
初始化通讯库。此步骤需要将主窗口句柄和应用程序实例传递给低级别堆栈以进行Windows消息传递。
使用设备地址
读/写
关闭
取消初始化通信库。
现在,在第二步中,DLL创建了一个不可见的窗口,用于与低级硬件堆栈进行通信。由于第二步是阻塞调用,我希望我的UI在此期间能够响应,以防需要很长时间才能连接。因此,我尝试使用线程或BeginInvoke调用异步连接。但我发现连接建立后,只要子窗口存在,应用程序窗口就会挂起。子窗口似乎阻止所有传入消息到主窗口。这似乎是因为子窗口是在另一个线程中创建的。
但我不希望连接在主线程中挂起UI。
我欢迎有关如何避免此问题的任何想法?提前谢谢。
-Harish
答案 0 :(得分:0)
必须在创建此句柄的线程上完成与窗口句柄的所有通信。这可能意味着所有对DLL的调用都应该在辅助线程上完成。
您可以尝试以下操作:
-
public static Form BackgroundForm;
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
new Thread(new ThreadStart(Secondary)).Start();
Application.Run(new MainForm());
}
static void Secondary()
{
BackgroundForm = new Form();
// Calling Handle creates the system HWND. You do not have to call Show
// or something similar on this Form to make the handle available or use
// Invoke or BeginInvoke.
var handle = BackgroundForm.Handle;
// Initialize the DLL here with the handle.
Application.Run();
// Unintialize the DLL.
}
Invoke
和BeginInvoke
执行此操作以获取此背景格式; Application.ExitThread()
或Invoke
进行BeginInvoke
。您看到主窗体被阻止的问题,可能是因为在DLL中创建的子窗口具有主窗体的句柄,因为它是父窗口,但这只是猜测。这也应该使用这个系统来解决。