The showdialog() method in thread/threading. Timer/task reported an error: “before ole can be called, the current thread must be set to single thread unit (STA) mode.”

Before ole can be called, the current thread must be set to single threaded unit (STA) mode. Make sure that your main function is marked with stathreadattribute.

Error environment:

1. In the thread thread, call the showdialog() method

2. In the thread timer, call the showdialog() method

3, calling the ShowDialog() method in the Task task.

Error exception:

When the. Showdialog() method is executed, the following error will appear: “before ole can be called, the current thread must be set to single threaded unit (STA) mode. Please make sure that your main function is marked with stathreadattribute.”

Error reason:

1. First of all, make sure that the main entry of the program is marked with stathreadattribute. If not, please add [stathread] to see if the problem is solved

2. Because this operation is executed in the newly created thread, the UI cannot be accessed, that is, calling ShowDialog () directly is indeed problematic. Non UI thread cannot open window

Solution:

1. Thread

By setting the apartmentstate property of the thread to apartmentstate   Enumeration value that controls the type of cell created.

Among them:

Sta: thread will create and enter a single thread unit;

MTA: thread will create and enter a multi thread unit;

Unknown: the apartmentstate property has not been set.

The code is as follows:

Thread th = new Thread(()=> new Form1().ShowDialog());
th.SetApartmentState(ApartmentState.STA);
th.Start();

This is a common practice on the Internet

2. System.threading.timer

See below!!

3. Task

Task encapsulates task, work content, not thread. A task may be executed on any thread, so the task does not provide thread properties, and the thread class should not be used in asynchronous methods. Moreover, the apartmentstate property of the thread should not be modified in the task, because the thread may execute other tasks. In other words, sta thread cannot be thread pool thread!!   See below!!


So!! Big move here!!!

👉 Multithreading interface should use control. Invoke delegate to let UI thread do it by itself 👈

this.Invoke(some   delegate);// Synchronization
or
this.begininvoke (some)   delegate);// Asynchronous

The code is as follows:

private void button1_Click(object sender, EventArgs e)
{
    Func<string> func = OFD;
    Task task = new Task(() =>
    {
        string res = (string)this.Invoke(func);//Synchronize! Let the UI threads do it themselves
    });
    task.Start();

}
private string OFD()
{
    OpenFileDialog dlg = new OpenFileDialog();
    if (dlg.ShowDialog() == DialogResult.OK)
    {
        string path = dlg.FileName;
        return path;
    }
    return null;
}

Read More: