2

我有两个线程。

线程 1:WPF 线程。显示一个包含所有信息的窗口。
线程 2:不断循环,接收信息并更新线程 1 中的窗口。

我有以下接口。

IModuleWindow
{
    void AddModule(IModule module);
    void RemoveModule(IModule module);
}

IModule
{
    UserControl GetSmallScreen();
    UserControl GetBigScreen();
}

IModuleWindow 由线程 1 中的 WPF 窗口
实现 IModule 由对象实现,在线程 2 中实例化,然后发送到线程 1。

我想将 IModule 中的 UserControls 添加到线程 1 中的 Window 对象中,并显示它们。IModule 对象在线程 2 中不断更新,它们必须更改其文本。

基本上这个想法是该程序应该显示线程 2 中对象的状态,该状态会不断更新。

在 WPF 中完成此任务的最佳方法是什么?

4

3 回答 3

2

IMO 最好的想法是使用BackgroundWorkerReportProgress ,方法和ProgressChanged事件非常方便。

ProgressChanged事件在 GUI 线程上引发,因此您可以直接对 GUI 执行更新。您的代码应如下所示:

// initialize the worker
BackgroundWorker backgroundWorker1 = new BackgroundWorker();
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
backgroundWorker1.RunWorkerAsync();


// thread 2 (BackgroundWorker) 
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    // main loop
    while(true) 
    {
        // time-consuming work
        // raise the event; use the state object to pass any information you need
        ReportProgress(0, state);
    }
}

// this code will run on the GUI thread
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    // get your state back
    object state = e.UserState;
    // update GUI with state
}
于 2012-08-27T10:02:00.723 回答
1

它帮助我了解我必须做什么。

场景一定是这样的:

ObservableCollection images = new ObservableCollection();
TaskFactory tFactory = new TaskFactory();

tFactory.StartNew(() =>
{
  for (int i = 0; i < 50; i++)
  {
    //GET IMAGE Path FROM SERVER
    System.Windows.Application.Current.Dispatcher
          .BeginInvoke((Action)delegate()
          {
            // UPDATE PROGRESS BAR IN UI
          });

     images.Add(("");
   }    
  }).ContinueWith(t =>
     {
       if (t.IsFaulted)
       {
          // EXCEPTION IF THREAD IS FAULT
          throw t.Exception;
        }
      System.Windows.Application.Current.Dispatcher
       .BeginInvoke((Action)delegate()
       {
          //PROCESS IMAGES AND DISPLAY
       });
    });

您必须使用System.Windows.Application.Current.Dispatcher.BeginInvoke()来更新 WPF 中的 UI。

于 2012-08-27T09:52:38.437 回答
1

能够使用在另一个线程上创建的控件会很好,这就是我想要的理想

简短的回答:忘记它。

UI 控件仅属于单个 UI 线程。您可以在这里做的最好的事情是在主线程中创建控件,在后台线程中准备数据,并再次在主(UI)线程中更新控件的属性。

对于数据准备,我建议使用TPL

于 2012-08-27T10:45:18.347 回答