调用线程不能访问这个对象,因为不同的线程拥有它“异常”

问题描述:

在我的项目中我有文本框,当事件发生时_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; 
     } 
+0

WPF or WinForms? – 2012-08-01 07:49:35

+0

@AdamHouldsworth WPF – tito11 2012-08-01 07:51:36

试试这个:

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

对不起,我编辑我的问题 – tito11 2012-08-01 07:53:47

+0

对于WPF,请参阅Jon的答案。 – logicnp 2012-08-01 07:54:51

由于技术原因,窗户和在一个线程创建的控件无法从其他线程访问。为了解决这个问题,你必须将控制访问操作(获取并设置Text)转发给相应的线程,WPF中的线程称为调度程序线程

通过调用StatTextBox.Dispatcher.Invoke(它是同步的,即直到处理完成才返回)或StatTextBox.Dispatcher.BeginInvoke(它是异步的并提供更好的性能)来完成此操作。

+0

感谢乔恩,但我不能在这里使用我的方法,因为它有一个参数..对不起我的坏英语 – tito11 2012-08-01 08:01:25

+0

@ tito11:当然,你可以,而不仅仅是一种方式。例如:'StatTextBox.Dispatcher.Invoke(this.AddNewState,“这里有一些文字”)'。虽然代码可以使用一些重组。 – Jon 2012-08-01 08:07:36

+1

感谢乔恩,但给我一个错误http://www.freeimagehosting.net/r8e1b – tito11 2012-08-01 08:19:46

如果您使用Windows窗体,则可以从与创建控件的位置相同的线程或使用编组访问窗口控件。

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

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

的终极解决方案: 找小时这个.. 你可以调用从任何你想要的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; 
    }