【问题标题】:Communicate Between two threads两个线程之间通信
【发布时间】:2010-11-17 19:52:42
【问题描述】:

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

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

【问题讨论】:

标签: c# .net multithreading events backgroundworker


【解决方案1】:

您不能从另一个线程更新 UI 对象。它们必须在 UI 线程中更新。尝试将此代码添加到 MainGrafik_ProgressUpdate(双进度)

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

         return;
    }

    ProgressBar = progress;
}

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      简而言之,在其他线程执行的上下文中在表单上调用它:

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

      【讨论】:

        猜你喜欢
        • 2011-10-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-07
        • 1970-01-01
        • 1970-01-01
        • 2017-01-14
        相关资源
        最近更新 更多