2014-03-24 175 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