2016-12-17 81 views
1

我想在后台加载新表单并在加载后显示它。 但我总是得到这个错误:“无效的跨线程访问”与代码: 如何使它工作?!在后台工作人员和showdialog加载新表格在完成的方法

public partial class f1 : Form 
{ 
    private Form f2; 
    public f1() 
    { 
     InitializeComponent(); 
     BackgroundWorker bgw = new BackgroundWorker(); 
     bgw.RunWorkerAsync(); 
     bgw.DoWork += new DoWorkEventHandler(dowork); 
     bgw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(completed); 
    } 
    void dowork(object sender, DoWorkEventArgs e) 
    { 
     f2 = new f2(); 
    } 

    void completed(object sender, RunWorkerCompletedEventArgs e) 
    { 
     f2.showdialog(); 
     this.Close(); 
    } 

} 
+2

它永远不会工作。您不能在后台线程上执行任何UI工作。无论如何,在这种特定情况下你会获得什么?如果你在构造函数中长时间运行的工作将代码移走,也许你可以卸载(部分)方法到后台线程。 –

+0

可能重复[无效的跨线程访问backgroundworker错误c#](http://stackoverflow.com/questions/28597958/invalid-cross-thread-access-backgroundworker-error-c-sharp) –

+1

错误的方法。你应该立即显示'f2'(顺便说一句,这是一个非常糟糕的类名**,因为它没有意义,甚至不遵循标准的命名约定)。一旦显示表格,你就可以从新表格开始后台处理。如果您不想立即显示新表单,那么您应该向用户提供一些反馈,以便他知道发生了什么情况。 – Phil1970

回答

0

您可能不得不将单独的数据载入窗体并将UI初始化形成两个不同的faze。

我已将您的代码示例更改为以下内容。

public partial class Form2 : Form 
     { 
      public Form2() 
      { 
       InitializeComponent(); 

       BackgroundWorker bgw = new BackgroundWorker(); 
       bgw.RunWorkerAsync(); 
       bgw.DoWork += new DoWorkEventHandler(dowork); 
       bgw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(completed); 
      } 
      void dowork(object sender, DoWorkEventArgs e) 
      {  
       e.Result = InitializeNeededDataToShowOnTheSecondform(); 
      } 


      void completed(object sender, RunWorkerCompletedEventArgs e) 
      { 
       BeginInvoke(new MethodInvoker(() => 
       { 
        var f2 = new Form3(e.Result); 
        f2.ShowDialog(); 
        this.Close(); 

       })); 
      } 

      private object InitializeNeededDataToShowOnTheSeconDform() 
      { 
//time consuming data initialization and/or any other time consuming process 
       return 10; 
      } 

     }