在两个线程之间进行通信

时间:2010-11-17 19:52:42

标签: c# .net multithreading events backgroundworker

我是这样的。它给了我错误。我删除了所有不需要的代码部分。它给了我这个错误

The calling thread cannot access this object because a different thread owns it.

 public partial class MainWindow : Window
{
    BackgroundWorker worker;
    Grafik MainGrafik;

    double ProgressBar
    {
        set { this.progressBarMain.Value = value; }
    }

    public MainWindow()
    {
        InitializeComponent();
        worker = new BackgroundWorker();
        worker.DoWork += new DoWorkEventHandler(worker_DoWork);

        MainGrafik = new Grafik();
        MainGrafik.ProgressUpdate += 
            new Grafik.ProgressUpdateDelegate(MainGrafik_ProgressUpdate);

        worker.RunWorkerAsync();
    }

    void MainGrafik_ProgressUpdate(double progress)
    {
        ProgressBar = progress;
    }


    void worker_DoWork(object sender, DoWorkEventArgs e)
    {
        while(true)
        {
            MainGrafik.Refresh();
            Thread.Sleep(2000);
        }
    }
}

class Grafik
{
    public delegate void ProgressUpdateDelegate(double progress, 
        DateTime currTime);
    public event ProgressUpdateDelegate ProgressUpdate;

    public void Refresh()
    {
            ProgressUpdate(5); // Just for testing
    }
}

3 个答案:

答案 0 :(得分:8)

您无法从其他线程更新UI对象。它们必须在UI线程中更新。尝试将此代码添加到MainGrafik_ProgressUpdate(双重进度)

void MainGragfik_ProgressUpdate(double progress)
{
    if (InvokeRequired)
    {
         BeginInvoke((MethodIvoker)(() =>
         {
             MainGragfik_ProgressUpdate(progress);
         }));

         return;
    }

    ProgressBar = progress;
}

答案 1 :(得分:0)

触发ProgressUpdate事件的线程是您的BackgroundWorker。 ProgressUpdate事件处理程序可能在该线程上运行,而不是在UI线程上运行。

答案 2 :(得分:0)

简单地在你的其他线程执行的上下文中调用它:

  void MainGrafik_ProgressUpdate(object sender, EventArgs e) { 
  Action<T> yourAction =>() yourAction;            

   if(yourForm.InvokeRequired)
        yourForm.Invoke(yourAction);
   else yourAction;

  }

或使用MethodInvoker(空白代表)

 void MainGrafik_ProgressUpdate(object sender, EventArgs e) { 
     MethodInvoker invoker = delegate(object sender, EventArgs e) {

        this.ProgressBar = whatever progress;
  };        


  }