简体   繁体   English

在两个线程之间通信

[英]Communicate Between two threads

I have sth like that. 我有这样的事。 It's giving me error. 这给了我错误。 I cut out all unneeded parts of code. 我删去了所有不需要的代码部分。 It is giving me this error 这给我这个错误

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
    }
}

You can't update UI objects from another thread. 您不能从另一个线程更新UI对象。 They have to be updated in the UI thread. 它们必须在UI线程中进行更新。 Try adding this code to the MainGrafik_ProgressUpdate(double progress) 尝试将此代码添加到MainGrafik_ProgressUpdate(双进度)

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

         return;
    }

    ProgressBar = progress;
}

The thread firing the ProgressUpdate event is your BackgroundWorker. 引发ProgressUpdate事件的线程是您的BackgroundWorker。 The ProgressUpdate event handlers are likely running on that thread, and not the UI thread. ProgressUpdate事件处理程序可能在该线程上运行,而不是在UI线程上运行。

in short call this on the form in the context of your other thread's execution: 简而言之,在其他线程执行的上下文中,在表单上调用此方法:

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

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

  }

Or with MethodInvoker (blank delegate) 或使用MethodInvoker(空白委托)

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

        this.ProgressBar = whatever progress;
  };        


  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM