In. NET, OpenFileDialog uses a solution that reports thread errors. netopenfiledialog
Yesterday, when I was doing a small demo for NPOI reading, I used OpenFileDialog to open the file. In the initial writing method, I wrote it directly in the button and clicked the event. An error is reported. The Code is as follows:
1 OpenFileDialog ofd = new OpenFileDialog (); 2 ofd. filter = "Microsoft Office Excel (*. xls ;*. xlsx) | *. xls ;*. xlsx "; 3 ofd. filterIndex = 1; 4 ofd. restoreDirectory = true; 5 6 7 if (ofd. showDialog () = DialogResult. OK) 8 {9 // check whether the file path is empty. 10 if (! String. IsNullOrEmpty (ofd. FileName) 11 {12 ReadFromExcelFile (ofd. FileName); 13} 14 else15 {16 this. textBox1.Text = "open an excel file"; 17} 18}
Or directly
using(OpenFileDialog ofd = new OpenFileDialog()){ ofd.ShowDialog(); }
Either way, an error is reported during code execution. The specific error is:
"System. threading. threadStateException "type of unprocessed exception in System. windows. forms. other information occurs in dll: The current thread must be set to single-threaded unit (STA) mode before OLE can be called. Make sure that your Main function has the STAThreadAttribute flag. This exception is thrown only when the debugger is attached to the process.
In this case, the query on the internet refers to a thread problem, that is, a thread conflict. I don't know which one to execute. The specific statement is as follows:
There are three types of thread models provided by COM: Single-Threaded Apartment (STA Single-thread suite) and Multithreaded Apartment (MTA multi-thread suite) and Neutral Apartment/Thread Neutral Apartment/Neutral Threaded Apartment (NA/TNA/NTA Neutral Thread suite, provided by COM + ).
A sta object can only be accessed by one thread, which is equivalent to a windows message loop. The implementation method is message loop. interfaces such as ActiveX controls and OLE document servers use the STA suite. An MTA object can be accessed by multiple threads. That is, the code of this object implements thread protection in its own method, ensuring that its status can be changed correctly.
Therefore, when creating and accessing an activex or ole object, you must set the thread mode to sta.
Then, in the Child thread, how should we use OpenFileDialog to not continue to report this error? The changed code is as follows:
1 /// <summary> 2 // open the excel document in a single thread 3 /// </summary> 4 /// <param name = "sender"> </param> 5 // <param name = "e"> </param> 6 private void btnXlx_Click (object sender, eventArgs e) 7 {8 this. textBox1.Text = string. empty; 9 10 System. threading. thread s = new System. threading. thread (new System. threading. threadStart (getExcel); 11 s. apartmentState = System. threading. apartmentState. STA; 12 s. start (); 13 14} 15 16 /// <summary> 17 // read the excel document address at 18 /// </summary> 19 private void getExcel () 20 {21 OpenFileDialog ofd = new OpenFileDialog (); 22 ofd. filter = "Microsoft Office Excel (*. xls ;*. xlsx) | *. xls ;*. xlsx "; 23 ofd. filterIndex = 1; 24 ofd. restoreDirectory = true; 25 26 27 if (ofd. showDialog () = DialogResult. OK) 28 {29 // check whether the file path is empty. 30 if (! String. isNullOrEmpty (ofd. fileName) 31 {32 ReadFromExcelFile (ofd. fileName); 33} 34 else35 {36 this. textBox1.Text = "open an excel file"; 37} 38} 39}
Is to separate the content of the thread execution to form a method, and then write and execute the single-thread statement of the sub-thread in the event. In this case, the thread Exception error will not be reported.
PS: If I search for online content, I can find a solution by adding [STAThread] to the front door of the Main function. There are other methods, the problem is not solved. My personal method may seem a little troublesome to the gods. If God has a better method, I would like to thank you very much and welcome to share it here !!