2014-03-24 32 views
0

我有一個工作應用程序,向網格添加新的RibbonTab和新的子控件。wpf後臺線程更新UI控制

我想提出這個動作在後臺線程的子控件可能需要一段時間從數據庫中收集數據等

我有下面的代碼至今:

Ribbon Ribbon_Main = new Ribbon(); 
Grid Grid_Main = new Grid(); 

Thread newthread2 = new Thread(new ThreadStart(delegate { Graphing_Template.add_report(); })); 
newthread2.SetApartmentState(ApartmentState.STA); //Is this required? 
newthread2.Start(); 


Class Graphing_Template() 
{ 
    static void add_report() 
    { 
    RibbonTab rt1 = new RibbonTab(); 
    MainWindow.Ribbon_Main.Items.Add(rt1); 
    // Create control with information from Database, etc. 
    // add control to MainWindow.Grid_Main 
    } 
} 

我想要在後臺創建新的報表控件,並在準備就緒時將其添加到主UI。

我去解決的辦法是:

 BackgroundWorker worker = new BackgroundWorker(); 
    worker.DoWork += delegate(object s, DoWorkEventArgs args) 
      { 
       DataTable dt1 = new DataTable(); 
       ---- Fill DataTable with 
       args.Result = datagrid_adventureworks_DT(); 
      }; 

worker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs args) 
      { 
       DataTable dt1 = (DataTable)args.Result; 
       Datagrid_Main.ItemsSource = dt1.AsDataView(); 
      }; 
+0

作爲一般規則,除非你是在UI線程不要觸摸UI對象。當然,在後臺線程中做一些咕嚕的工作,然後通過調度程序將UI更新編組到UI線程。 – Cameron

+0

我可以生成兩個子對象,然後將它們傳遞迴UI線程? – user3329538

+0

我不知道WPF給出了一個明確的答案,對不起。我懷疑它會起作用,但我知道它不會用winforms,例如,因爲Win32 UI對象只能由創建它們的線程觸及(WPF不使用Win32 UI對象來實現像按鈕,等等。)。 – Cameron

回答

1
private void Window_Loaded(object sender, RoutedEventArgs e) 
    { 
     Test4(); 

    } 
    private void Test1() 
    { 
     while (true) 
     { 
      this.Title = DateTime.Now.ToString(); 
      System.Threading.Thread.Sleep(5000); //locks up app 
     } 
    } 
    private void Test2() 
    { 
     var thd = new System.Threading.Thread(() => { 
      while (true) 
      { 
       this.Title = DateTime.Now.ToString(); //exception 
       System.Threading.Thread.Sleep(5000); 
      }    
     }); 
     thd.Start(); 
    } 

    private void Test3() 
    { //do the work on the background thread 
     var thd = new System.Threading.Thread(() => 
     { 
      while (true) 
      { //use dispatcher to manipulate the UI 
       this.Dispatcher.BeginInvoke((Action)(() 
        => { this.Title = DateTime.Now.ToString(); 
       })); 

       System.Threading.Thread.Sleep(5000); 

       //there's nothing to ever stop this thread! 
      } 
     }); 
     thd.Start(); 
    } 

    private async void Test4() 
    { //if you are using .Net 4.5 you can use the Async keyword 
     //I _think_ any computation in your async method runs on the UI thread, 
     //so don't use this for ray tracing, 
     //but for DB or network access your workstation can get on with 
     //other (UI) work whilst it's waiting 
     while (true) 
     { 
      await Task.Run(() => { System.Threading.Thread.Sleep(5000); }); 
      this.Title = DateTime.Now.ToString(); 
     } 
    } 
+0

我需要對Test3進行一些進一步的測試......因爲我遇到了一些問題。稍後會澄清。 – user3329538