【问题标题】:Two threads communicating两个线程通信
【发布时间】:2011-09-27 08:53:26
【问题描述】:

我有一个richTextBoxLog,它是公共的和静态的。

在我声明它之后,我启动一个新线程来初始化名为proba 的新变量。 richTextBoxLog 应该从 proba 获取值。

问题是,proba 需要时间来初始化,而我希望 richTextBoxLogproba 正在初始化时进行初始化。

我想写这样的东西:

richTextBoxLogFile.richTextBoxLog.Text += proba;

但是,当我在前面提到的线程调用的方法中编写它时,我得到一个异常:"Cross-thread operation not valid: Control 'richTextBoxLog' accessed from a thread other than the thread it was created on."

我可以这样写吗:停止线程,然后初始化richTextBoxLog,然后再次启动线程,然后停止它,并且在初始化richTextBoxLog结束时同样继续。

编辑:我尝试使用这个:

context.Post(new SendOrPostCallback(newMethod), (object)proba);

其中context是主线程的上下文,newMethod初始化richTextBoxLog的值。但是,这个调用是在新线程启动的方法中,在一个while循环中:

   while (-1 != (ch = _reader.Read()))
        {
            Console.Write((char)ch);
            proba += ((char)ch).ToString();
            context.Post(new SendOrPostCallback(newMethod), (object)proba);                
        }
        _complete.Set();
    }

我现在遇到的问题是,我希望每次进入 while 循环时都调用 newMethod。但是,发生的事情是:while 循环结束,然后 newMethod 被输入了大约一千次。

【问题讨论】:

  • 如果你想等待'proba'和richTextBoxLog初始化然后让它们合作..你需要synchronization在初始化结束时标记和发现
  • 问题是我在一个类中声明了richTextBoxLog,而线程是在另一个类中启动的。

标签: c# multithreading exception


【解决方案1】:

您需要使用 proba 调用该方法:

System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke(
     new Action(() => 
         {
               //do stuff with proba
         }
     ));

//编辑:

等等,这有点复杂。调度程序是一个对象,它可以简单地表示来自其他线程的执行方法。这意味着您需要使用 proba 在线程中创建一个调度程序,并在您的其他线程中使用该调度程序来执行上述方法。

【讨论】:

    【解决方案2】:

    我会考虑使用BackgroundWorker - 这样的操作可以减轻很多痛苦。

    http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx

    否则您需要使用 Control.Invoke 再次同步线程 - http://msdn.microsoft.com/en-us/library/system.windows.forms.control.invoke.aspx(您不应该而且通常不能从 UI 线程以外的任何地方访问 UI)

    【讨论】:

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