调用线程无法访问此对象,因为另一个线程拥有它“异常”

时间:2012-08-01 07:47:45

标签: c# wpf exception

在我的项目中我有文本框,当事件触发_rtpAudioChannel_ChannelStateChanged 我得到此异常调用线程无法访问此对象,因为另一个线程拥有它

      void _rtpAudioChannel_ChannelStateChanged(object sender, RtpStateChangedEventArgs<RtpChannelState> e)
      {
            AddNewState("some text here");
      }


      public void AddNewState(string state)
      {
            StatTextBox.Text = state + "\n" + StatTextBox.Text;
      }

4 个答案:

答案 0 :(得分:1)

由于技术原因,无法从任何其他线程访问在一个线程中创建的窗口和控件。要解决此问题,您必须将控制访问操作(获取并设置Text)“转发”到相应的线程,该线程在WPF中称为调度程序线程

通过调用StatTextBox.Dispatcher.Invoke(这是同步的,即在处理完成之前不返回)或StatTextBox.Dispatcher.BeginInvoke(这是异步的并提供更好的性能)来执行此操作。

答案 1 :(得分:1)

最终解决方案: 看了几个小时...... 您可以从任何地方调用SetMSG(文本)功能。 它会将StatTextBox.Text设置为文本。

 public void SetMSG(string text){

        if (StatTextBox.Dispatcher.CheckAccess())
        {
            StatTextBox.Text = text;
        }
        else
        {
            SetTextCallback d = new SetTextCallback(SetText);
            StatTextBox.Dispatcher.Invoke(DispatcherPriority.Normal, d, text);
        }
    }
    delegate void SetTextCallBack(string Text);

    public void SetText(string text){
        StatTextBox.Text=text;
    }  

答案 2 :(得分:0)

试试这个:

    StatTextBox.Invoke((MethodInvoker)delegate()
    {
        StatTextBox.Text = "some text here" + "\n" + StatTextBox.Text;
    }

答案 3 :(得分:0)

如果您使用的是Windows窗体,则应该从创建控件的同一个线程访问窗口控件,或者使用编组。

您可以在代码中使用此变体:

var lambda = () => StatTextBox.Text = "some text here" + "\n" + StatTextBox.Text;
if (StatTextBox.InvokeRequired)
{
    control.Invoke(lambda, new object[0]);
}
else
{
    lambda();
}