4

I am working on an application that communicates with an external device via a third-party COM library. I'm attempting to have all communication to the device go through a background thread both to prevent problems with communication from screwing up my app and to get rid of some other complexities introduced by having communication in the UI thread.

The problem is that whenever something happens that causes the main UI thread to block (i.e. MessageBox.Show being called or even just moving the window around the screen), the communication with the device on the background thread stops as well.

Is there any way (short of a totally separate process) to break the two threads far enough apart that they won't interfere with each other? (Note, the exact same code with some math calculations to slow things down a bit works just fine, it's only when I'm using the COM library that I have the issue)

3
  • 3
    That seems very strange. Without seeing your code, it's hard to know for sure why making the UI thread busy slows down your other thread. Is there anything on the worker thread that could possibly be waiting for the UI thread to do something? Commented Apr 26, 2010 at 20:05
  • 1
    Is your background thread telling the UI to pop up a messagebox using Invoke? Commented Apr 26, 2010 at 20:08
  • @Paolo, It sounds like it's something that would occur much more frequently than popping up a message box or something like that. Presumably he's not popping up so many message boxes that grabbing the window and moving it around is causing a slowdown. :) Commented Apr 26, 2010 at 20:12

2 Answers 2

13

The behavior you observe can be explained if the following two conditions are true.

  • The 3rd party COM library is designed to be run in a single threaded apartment
  • You are creating an instance of a class from the library on the UI thread

Since the UI thread runs in an STA (single threaded apartment) and the COM class was created on that thread then all calls to the class originating from a thread other than the UI thread will be marshalled onto the UI thread itself. If the UI thread is blocked then all calls to the COM class will block as well.

Sign up to request clarification or add additional context in comments.

1 Comment

That did the trick. The COM object was being created in the UI thread prior to being handed off to the worker thread. When I moved that into the worker thread itself, the problem went away.
2

I would like to fill in on Brian's answer.

Could it be that you are forgetting to call TrySetApartmentState(ApartmentState.STA) for your worker thread? If so, I believe your worker thread is running in MTA by default and all STA objects get created on a separate STA thread (possibly even main UI thread). You should make sure your worker thread joins a STA and see if that helps.

Other than this, COM objects can be registered as main-STA. IIRC, this is uncommon. Main-STA objects MUST live in the main UI thread. If this happens to be your case, I believe your only option is to resort to worker process instead of a worker thread.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.