开发者

Communicate Between two threads

开发者 https://www.devze.com 2023-01-25 08:58 出处:网络
I have sth like that. It\'s giving me error. I cut out all unneeded parts of code. It is giving me this error

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. They have to be updated in the UI thread. Try adding this code to the MainGrafik_ProgressUpdate(double progress)

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

         return;
    }

    ProgressBar = progress;
}


The thread firing the ProgressUpdate event is your BackgroundWorker. The ProgressUpdate event handlers are likely running on that thread, and not the UI thread.


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)

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

        this.ProgressBar = whatever progress;
  };        


  }
0

精彩评论

暂无评论...
验证码 换一张
取 消