How to Make a Background Worker Thread Set to Single Thread Apartment

How can I make a background worker thread set to Single Thread Apartment?

This is not possible, BGW uses a threadpool thread. TP threads are always MTA, it cannot be changed. You will have to use a regular Thread, call SetApartmentState() before you start it. This thread also should pump a message loop, call Application.Run().

Maybe you ought to consider calling this code from the UI thread. Because in all likelihood, the COM server is running its methods on the UI thread anyway. Marshaling calls from a worker thread to the STA thread that created the COM server is automatic, COM takes care of it.

Or take the bull by the horns and marshal yourself. You can create your own STA thread to give the server a happy home. You'll find code in this post, be sure to create the COM object in your Initialize() override.

Current thread must be set to single thread apartment (STA) error in copy string to clipboard

Make sure thread that runs the code is marked with [STAThread] attribute. For WinForm and console based apps it is generally Main method

Put [STAThread] above your main method:

[STAThread]
static void Main()
{
}

For WinForms it is usually in generated Main.cs file that you can edit if necessary (it will not be re-generated on changes). For console it's were you define the Main.

If you can't control the thread (i.e. you are writing a library or main app is locked by some reason) you can instead run code that accesses clipboard on specially configured thread (.SetApartmentState(ApartmentState.STA)) as shown in another answer.

Single thread apartment issue

Is Main(string[] args) really your entry point?

Maybe you have another Main() overload with no parameters. Or some other Main() in another class. Please open Project properties and look for the start object.

which thread does backgroundworker completed event handler run on?

It's going to be run in the same thread that BackgroundWorker is in, ie most usually the UI thread.

Passing collection from backgroundworker DoWork to backgroundworker Completed and perform a foreach

You have to cast e.Result in Completed handler from object to PrincipalSearchResult<Principal> in order to iterate through it.

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//Add each computername to combobox
PrincipalSearchResult<Principal> results = (PrincipalSearchResult<Principal>)e.Result;
foreach (Principal PC in results)
{
comboBox1.Items.Add(PC.ToString());
}
}

Edit:

PrincipalSearcher can't be used in Background Worker, because it's uses of COM component that requires Single-threaded Apartment (STA). Background Worker thread runs in multithreaded apartment (MTA). ApartmentState can be set using Thread.SetApartmentState, but it must be called before thread starts (so it can't be used to change ApartmentState of BackgroundWorker's working thread).



Related Topics



Leave a reply



Submit