1)Issue:
private void button1_Click(object sender, RoutedEventArgs e) { BackgroundWorker bw_test = new BackgroundWorker(); bw_test.DoWork += new DoWorkEventHandler(bw_test_DoWork); bw_test.RunWorkerAsync(); } void bw_test_DoWork(object sender, DoWorkEventArgs e) { try { //show another Forms InputCvtDefManul put = new InputCvtDefManul(); put.ShowDialog(); } catch (Exception ex) { } }
Encounter this error: The calling thread must be STA, because many UI components require this
2) 經過嘗試,有兩種方式可以解決:
A.這種方法網上有很多,如果不需要交互(等待顯示Form的數據),或者僅僅是更新其顯示Form的數據,這個就足夠解決了。
void bw_test_DoWork(object sender, DoWorkEventArgs e) { try { //InputCvtDefManul put = new InputCvtDefManul(); //put.ShowDialog(); Thread newWindowThread = new Thread(new ThreadStart(() => { Dispatcher.Invoke(new Action(() => { InputCvtDefManul ss = new InputCvtDefManul(); ss.ShowDialog(); })); })); newWindowThread.Start(); newWindowThread.SetApartmentState(ApartmentState.STA); newWindowThread.IsBackground = false; newWindowThread.Start(); } catch (Exception ex) { } }
B.使用當前進程:
void bw_test_DoWork(object sender, DoWorkEventArgs e) { try { System.Windows.Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, new DoMywork(ThreadStartingPoint)); MessageBox.Show("iii", "Info", MessageBoxButton.OK, MessageBoxImage.Information); } catch (Exception ex) { } } private delegate void DoMywork(); private void ThreadStartingPoint() { InputCvtDefManul put = new InputCvtDefManul(); put.ShowDialog(); }
這樣的結果是只有在另起的Form關閉后才會彈出一個MessageBox。(異步)