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
A Timeout Occured After 30000Ms Selecting a Server Using Compositeserverselector
C#: How to Get an Object by the Name Stored in String
Get List of Zero Reference Codes in Visual Studio
Programmatic Control of Virtual Desktops in Windows 10
ASP.NET Core Model Binding Error Messages Localization
How to Define a Method in Razor
When Is a C# Value/Object Copied and When Is Its Reference Copied
Could We Save Delegates in a File (C#)
How to Load Assembly at Runtime and Create Class Instance
Unity Create UI Control from Script
How to Make a Background Worker Thread Set to Single Thread Apartment
Unrolled Loop Works, for Loop Does Not Work
Open File Dialog and Select a File Using Wpf Controls and C#
Remove File Extension from a File Name String
Send Http Post Message in ASP.NET Core Using Httpclient Postasjsonasync
How to Display the Displayattribute.Description Attribute Value