I am writing a small test application to test a communication interface. The communication interface is written in C++ (a DLL) and the test application using C#. The communication interface in turn talks to a low level hardware stack which uses windows messages to transmit and receive data. In order to achieve this, the commuication interface DLL creates an invisible child window whose parent is the C# test application window. The sequence to talk to the hardware is as follows :

Initialize the communication library. This step expects the main window handle and application instance which is passed to the low level stack for windows messaging.

Connect using the device address

Read/Write

Close

Deinitialize the communication library.

Now in the 2nd step, the DLL creates an invisible window to communicate with the low level hardware stack. Since the 2nd step is a blocking call, I want my UI to be responsive during this time in case it takes a long time to connect. Therefore, I try to connect asynchronously using a thread or a BeginInvoke call. But I observe that after the connection is established, the application window hangs as long as the child window exists. The child window seems to block all incoming messages to the main window. This seems to be because the child window gets created in another thread.

But I dont want want the connect to be in the main thread as it hangs the UI.

I would welcome any ideas on how to avoid this problem ? Thanks in advance.

Just curious as why 2 is a blocking call? Is your code keep polling to see if device is connected? As a solution, why do you create child window - create top level message-only window (msdn.microsoft.com/en-us/library/…).
–
VinayCOct 25 '10 at 13:31

Hi Vinay, I do not create the child window. I only use the DLL whose developer has done it that way. The DLL internally I guess has a timeout to know if the connection was done. This is a very large timeout and thus has a blocking effect on my application. A part of the problem is also because of the communication stack provider
–
HIyerOct 25 '10 at 13:37

1 Answer
1

All communication with a window handle must be done on the thread this handle was created on. This probably means that all calls to the DLL should be done on the secondary thread.

You can try the following:

Before initializing the DLL, start a background thread;

On that thread, create a WinForms window you do not show. You can do this like this:

-

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

Then, initialize the DLL with the handle you got from the background form;

When you need to do calls to the DLL, do this using Invoke and BeginInvoke to this background form;

Once it's time to shut down your application, do an Application.ExitThread() through a Invoke or BeginInvoke.

The problem you are seeing with the main form being blocked, is probably because the child window created in the DLL has the main form's handle as it's parent Window, but that's just a guess. This should probably also be solved using this system.