Why can't we change the state of the apartment in the ThreadPool thread and why don't we need MessagePump when ShowDialog is used?

Recently, I came across a situation where I wanted to display the form in another stream (and not in the main / user stream). I used thread threadpool. RCW is placed on the form (for the COM component). Creating an instance of the form gave me the exception that the stream must be an STA. I tried to set the state of the apartment as STA. But that didn't work either. I finally ended up creating the stream explicitly, and it worked (I used ShowDialog and didn't need to create a pump to measure the frequency).

EDIT:

  • I know threads are threadpool MTA. But why can't it be installed in the STA? Just wondering about that.
  • Another question that my head just appeared is: why don't we need a message message when Showdialog () (to
    display of form) is used
+6
multithreading c # winforms
source share
2 answers

The apartment is selected by calling CoInitializeEx (). The thread in the thread pool has already made this call, changing the apartment after this call is impossible.

The fact that the thread pool chose MTA makes sense, it is still designed as a workflow and should not be blocked by calls to methods that need to be marshaled. When choosing a single-threaded apartment, an additional requirement for pumping the message loop is required. Something you would never expect from a threadpool thread.

A message loop is needed because the car that uses COM to march a call made in another thread. This call must be β€œinserted” into the STA stream, which is only possible if the stream is in a known idle state. If this is not the case, such a call will cause serious reconnection problems. This sometimes happens even if the flow pumps the cycle.

You did not need to download the message pipeline using Application.Run (), because ShowDialog () starts its own message loop. This is how he gets modality. This nested loop ends as soon as the dialog closes.

+8
source share

You should not rely on the specific behavior of pool thread threads. In general, a thread in threadpool should be replaced at any time by the CLR, without your knowledge. Thread pool threads are designed to be used with simple tasks, preferably with short deadlines.

If you want to have fine-grained control over stream settings, you must create a dedicated stream. Setting the condition of the apartment is a great example of this.


In addition to the above theoretical reasons, there is a practical problem with what you are trying. Form hosting in the second thread does not work (without a lot of extra work). Forms must run in the same thread as in the message - otherwise they will not receive any Windows messages and will not be updated properly.

You can create the form in a separate thread if you are implementing the full message flow for that thread, but it is usually best to just put your work items in the background threads and use asynchronous programming methods to keep them responsive from the moment you create the user interface.

+8
source share

All Articles