Error:The calling thread cannot access the object because different thread owns it :WPF Browser App
- Hello TO All,
Actually i m creating a P2P voice chatting application its working fine in windows application but when i use the same code in WPF browser application it gives the following error:
Error:The calling thread cannot access the object because different thread owns it
There is no error at compile time.
System.InvalidOperationException was unhandled
Message="The calling thread cannot access this object because a different thread owns it."
Source="WindowsBase"
StackTrace:
at System.Windows.Threading.Dispatcher.VerifyAccess()
at System.Windows.Threading.DispatcherObject.VerifyAccess()
at System.Windows.DependencyObject.GetValue(DependencyProperty dp)
at System.Windows.Controls.TextBox.get_Text()
at WPF_Browser_VoiceChat_Final.Page1.Voice_In() in D:\WPF_Browser_VoiceChat_Final\WPF_Browser_VoiceChat_Final\Page1.xaml.cs:line 62
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
Error comes when code goes to below code:
private void Voice_In()
{
byte[] br;
socket.Bind(new IPEndPoint(IPAddress.Any, int.Parse(this.txtReceivingPort.Text))); //Here comes error.
while (true)
{
br = new byte[16384];
socket.Receive(br);
m_Fifo.Write(br, 0, br.Length);
}
}
If there is any sample on the net in wpf browser application please refer me.
Thanks in advance
With Best Regards Hardeep Singh Bhullar
Answers
- Hi,
This is because you are trying to update the UI from a different thread,different from the one that owns the element
Use a dispatcher to update the UI.This should solve your issue
See this link for some more info
Thank You
Please mark posts as answers/helpful if it answers your query. This would be helpful for others facing the same kind of problem- Edited byRahul P Nath Tuesday, November 03, 2009 11:55 AMAdded the link
- Marked As Answer byhardeepbhullar Tuesday, November 03, 2009 12:24 PM
- Hi,
The solution is use Dispatcher.BeginInvoke or Dispathcher.Invoke.
u must invoke the "socket.Bind(new IPEndPoint(IPAddress.Any, int.Parse(this.txtReceivingPort.Text))); " delegate inside the Dispatcher.BeginInvoke or Dispathcher.Invoke
Regards,
K.Kesavan- Marked As Answer byhardeepbhullar Tuesday, November 03, 2009 12:24 PM
Hi There,
Well, to be totally honest as soon as i saw your question I started laughing coz i went thru the same problem and it drove me insane.
What I was trying to do, was to access a story board and modify it while it is in action...and all I got was “you can guess”
Message="The calling thread cannot access this object because a different thread owns it."
Anyway, the following code snippet worked for me like a charm hope it helps...Good Luckthis.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() => { //Your Code Goes Here }));
p.s. you gonna need to use system.windows.threading- Marked As Answer byhardeepbhullar Tuesday, November 03, 2009 12:24 PM
- Hello Hardeep Singh Bhullar,
From the given code, based on my understanding, your requirement is to send message in a background thread.
So we cannot put all the handler to the Dispatcher querer.
If so, all action is put in the UI thread. The program hangs.
In the Voice_Out method. The access to the UI control is to get the Textbox's text string.
We only need to put the this on the Invoke deletegate.
try to revise:private void Voice_Out(IntPtr data, int size) { //for Recorder if (m_RecBuffer == null || m_RecBuffer.Length < size) m_RecBuffer = new byte[size]; System.Runtime.InteropServices.Marshal.Copy(data, m_RecBuffer, 0, size); this.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() => { //Microphone ==> data ==> m_RecBuffer ==> m_Fifo socket.SendTo(m_RecBuffer, new IPEndPoint(IPAddress.Parse(textBox1.Text), int.Parse(this.txtSendingPort.Text))); })); }
We can also use DispatcherPriority.Send priority.private void Voice_Out(IntPtr data, int size) { //for Recorder if (m_RecBuffer == null || m_RecBuffer.Length < size) m_RecBuffer = new byte[size]; System.Runtime.InteropServices.Marshal.Copy(data, m_RecBuffer, 0, size); IPEndPoint m_endPoint; this.Dispatcher.Invoke( DispatcherPriority.Normal, (Action)(() => { //get the end point. m_endPoint = new IPEndPoint(IPAddress.Parse(textBox1.Text), int.Parse(this.txtSendingPort.Text)); } )); socket.SendTo(m_endPoint); }
Thanks.
Please mark the replies as answers if they help and unmark them if they provide no help- Marked As Answer byhardeepbhullar Wednesday, November 04, 2009 1:25 PM
- I'm guessing you have a circular deadlock. With Dispatcher.Invoke(), you block the calling thread until the invoked delegate returns. As alternative, if you don't need a returned value (ie. the method's return is void), use BeginInvoke(). I'm guessing you have (maybe done automatically by the CLR?) two threads:
1) The "socket" thread.
2) The UI thread.
By dispatching the entire socket.bind() to the UI thread, the socket thread is blocked until this returns. If now in your UI thread you have the socket.Receive() running, this may dispatch to the socket-thread, which is still blocked.
Therefore:
- Use Dispatch.BeginInvoke(), if possible. This can be done if this is a fire-and-forget thing, such as myUIElement.Text = "bla";
- Only dispatch the part which absolutely has to be done in the UI-Thread. In your case, only getting this.txtSendingPort.Text has to be done there. In (minimal) code:
Kind regards,string sendingPortText = (string) this.Dispatcher.Invoke(new Func<string>(() => this.txtSendingPort.Text;));
Daniel Rose- Marked As Answer byhardeepbhullar Wednesday, November 04, 2009 1:26 PM
Hi!
You have this:
sendingPortText = (string)this.Dispatcher.Invoke(new Func<string>(() => this.txtSendingPort.Text));
So invoking socket.Bind() on the UI-Thread shouldn't be needed anymore:
Replace:
this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(() =>
{
_socket.Bind(new IPEndPoint(IPAddress.Any, int.Parse(sendingPortText)));
}));
with:
_socket.Bind(new IPEndPoint(IPAddress.Any, int.Parse(sendingPortText)));
Since you used BeginInvoke above, Voice_In() immediately proceeds. However, the whole socket.Bind() will take some time until it is finished. Thus you get an error on the socket.Receive, since it isn't done with socket.Bind() yet. By removing the now unnecessary call to the Dispatcher, you'll only proceed once Bind() is done, so you can remove the Thread.Sleep().
Similarly, in Voice_Out(), the large Dispatcher-block is also unnecessary.- Marked As Answer byhardeepbhullar Thursday, November 05, 2009 8:22 AM
All Replies
- Hi,
This is because you are trying to update the UI from a different thread,different from the one that owns the element
Use a dispatcher to update the UI.This should solve your issue
See this link for some more info
Thank You
Please mark posts as answers/helpful if it answers your query. This would be helpful for others facing the same kind of problem- Edited byRahul P Nath Tuesday, November 03, 2009 11:55 AMAdded the link
- Marked As Answer byhardeepbhullar Tuesday, November 03, 2009 12:24 PM
- Hi,
The solution is use Dispatcher.BeginInvoke or Dispathcher.Invoke.
u must invoke the "socket.Bind(new IPEndPoint(IPAddress.Any, int.Parse(this.txtReceivingPort.Text))); " delegate inside the Dispatcher.BeginInvoke or Dispathcher.Invoke
Regards,
K.Kesavan- Marked As Answer byhardeepbhullar Tuesday, November 03, 2009 12:24 PM
Hi There,
Well, to be totally honest as soon as i saw your question I started laughing coz i went thru the same problem and it drove me insane.
What I was trying to do, was to access a story board and modify it while it is in action...and all I got was “you can guess”
Message="The calling thread cannot access this object because a different thread owns it."
Anyway, the following code snippet worked for me like a charm hope it helps...Good Luckthis.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() => { //Your Code Goes Here }));
p.s. you gonna need to use system.windows.threading- Marked As Answer byhardeepbhullar Tuesday, November 03, 2009 12:24 PM
- Hello To All My Friends ,
This solved my problem but hanging my application. Actually i m new in threading and P2P.
can you please help me
My improved code goes here:
private void Voice_In()
{
byte[] br;
this.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() =>
{
socket.Bind(new IPEndPoint(IPAddress.Any, int.Parse(this.txtReceivingPort.Text)));
}));
while (true)
{
br = new byte[16384];
socket.Receive(br);
m_Fifo.Write(br, 0, br.Length);
}
}
Voice out code goes here:
private void Voice_Out(IntPtr data, int size)
{
//for Recorder
if (m_RecBuffer == null || m_RecBuffer.Length < size)
m_RecBuffer = new byte[size];
System.Runtime.InteropServices.Marshal.Copy(data, m_RecBuffer, 0, size);
this.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() =>
{
//Microphone ==> data ==> m_RecBuffer ==> m_Fifo
socket.SendTo(m_RecBuffer, new IPEndPoint(IPAddress.Parse(textBox1.Text), int.Parse(this.txtSendingPort.Text)));
}));
}
I m starting my thread in Page 's constructor
public Page1()
{
InitializeComponent();
socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
thread = new Thread(new ThreadStart(Voice_In));
}
With Best Regards Hardeep Singh Bhullar - Hello Hardeep Singh Bhullar,
From the given code, based on my understanding, your requirement is to send message in a background thread.
So we cannot put all the handler to the Dispatcher querer.
If so, all action is put in the UI thread. The program hangs.
In the Voice_Out method. The access to the UI control is to get the Textbox's text string.
We only need to put the this on the Invoke deletegate.
try to revise:private void Voice_Out(IntPtr data, int size) { //for Recorder if (m_RecBuffer == null || m_RecBuffer.Length < size) m_RecBuffer = new byte[size]; System.Runtime.InteropServices.Marshal.Copy(data, m_RecBuffer, 0, size); this.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() => { //Microphone ==> data ==> m_RecBuffer ==> m_Fifo socket.SendTo(m_RecBuffer, new IPEndPoint(IPAddress.Parse(textBox1.Text), int.Parse(this.txtSendingPort.Text))); })); }
We can also use DispatcherPriority.Send priority.private void Voice_Out(IntPtr data, int size) { //for Recorder if (m_RecBuffer == null || m_RecBuffer.Length < size) m_RecBuffer = new byte[size]; System.Runtime.InteropServices.Marshal.Copy(data, m_RecBuffer, 0, size); IPEndPoint m_endPoint; this.Dispatcher.Invoke( DispatcherPriority.Normal, (Action)(() => { //get the end point. m_endPoint = new IPEndPoint(IPAddress.Parse(textBox1.Text), int.Parse(this.txtSendingPort.Text)); } )); socket.SendTo(m_endPoint); }
Thanks.
Please mark the replies as answers if they help and unmark them if they provide no help- Marked As Answer byhardeepbhullar Wednesday, November 04, 2009 1:25 PM
- Hello Hua Chen,
First of all thanks for reply .
Actually the problem is not in Voice_Out() its in Voice_In()
Application getting hanged when it comes to Voice_In()
Please see:
private void Voice_In()
{
byte[] br;
this.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() =>
{
socket.Bind(new IPEndPoint(IPAddress.Any, int.Parse(this.txtSendingPort.Text)));
}));
while (true)
{
br = new byte[16384];
socket.Receive(br); ////////////////Here its getting hanged.... application stops here
m_Fifo.Write(br, 0, br.Length);
}
}
Please help me looking forward for your reply.....
Thanks in advance
With Best Regards Hardeep Singh Bhullar - I'm guessing you have a circular deadlock. With Dispatcher.Invoke(), you block the calling thread until the invoked delegate returns. As alternative, if you don't need a returned value (ie. the method's return is void), use BeginInvoke(). I'm guessing you have (maybe done automatically by the CLR?) two threads:
1) The "socket" thread.
2) The UI thread.
By dispatching the entire socket.bind() to the UI thread, the socket thread is blocked until this returns. If now in your UI thread you have the socket.Receive() running, this may dispatch to the socket-thread, which is still blocked.
Therefore:
- Use Dispatch.BeginInvoke(), if possible. This can be done if this is a fire-and-forget thing, such as myUIElement.Text = "bla";
- Only dispatch the part which absolutely has to be done in the UI-Thread. In your case, only getting this.txtSendingPort.Text has to be done there. In (minimal) code:
Kind regards,string sendingPortText = (string) this.Dispatcher.Invoke(new Func<string>(() => this.txtSendingPort.Text;));
Daniel Rose- Marked As Answer byhardeepbhullar Wednesday, November 04, 2009 1:26 PM
- Hello To All,
Thanks everybody for solving my issue in p2p voice chatting its working fine but i have to give some sleep time, somewhere reference is not coming to:
_socket.Receive(br); //error comes here
and the final working code is :
private void Voice_In()
{
bool firstTime = true;
sendingPortText = (string)this.Dispatcher.Invoke(new Func<string>(() => this.txtSendingPort.Text));
byte[] br;
this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(() =>
{
_socket.Bind(new IPEndPoint(IPAddress.Any, int.Parse(sendingPortText)));
}));
while (true)
{
br = new byte[16384];
if (firstTime)
{
firstTime = false;
Thread.Sleep(250);
}
_socket.Receive(br); //An invalid argument was supplied ....... //Error comes if i don't use sleep time or if i go through break point it does not give error
m_Fifo.Write(br, 0, br.Length);
}
}
private void Voice_Out(IntPtr data, int size)
{
string strOtherMachineIP = (string)this.Dispatcher.Invoke(new Func<string>(() => this.textBox1.Text));
//for Recorder
if (m_RecBuffer == null || m_RecBuffer.Length < size)
m_RecBuffer = new byte[size];
System.Runtime.InteropServices.Marshal.Copy(data, m_RecBuffer, 0, size);
IPEndPoint m_endPoint;
this.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() =>
{
//Microphone ==> data ==> m_RecBuffer ==> m_Fifo
//get the end point.
m_endPoint = new IPEndPoint(IPAddress.Parse(strOtherMachineIP), int.Parse(sendingPortText));
// _socket.SendTo(m_RecBuffer, new IPEndPoint(IPAddress.Parse(strOtherMachineIP), int.Parse(sendingPortText)));
_socket.SendTo(m_RecBuffer, m_endPoint);
}
));
}
Please suggest me if i am making mistake anywhere.Even if u require whole code i can provide
With Best Regards Hardeep Singh Bhullar Hi!
You have this:
sendingPortText = (string)this.Dispatcher.Invoke(new Func<string>(() => this.txtSendingPort.Text));
So invoking socket.Bind() on the UI-Thread shouldn't be needed anymore:
Replace:
this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(() =>
{
_socket.Bind(new IPEndPoint(IPAddress.Any, int.Parse(sendingPortText)));
}));
with:
_socket.Bind(new IPEndPoint(IPAddress.Any, int.Parse(sendingPortText)));
Since you used BeginInvoke above, Voice_In() immediately proceeds. However, the whole socket.Bind() will take some time until it is finished. Thus you get an error on the socket.Receive, since it isn't done with socket.Bind() yet. By removing the now unnecessary call to the Dispatcher, you'll only proceed once Bind() is done, so you can remove the Thread.Sleep().
Similarly, in Voice_Out(), the large Dispatcher-block is also unnecessary.- Marked As Answer byhardeepbhullar Thursday, November 05, 2009 8:22 AM
- Hello DanielRose,
Actually my application is running successfully but when i stop it and try to dispose all the object i m again getting my application hanged here is my Stop()
:::::
private WaveOutPlayer m_Player;
private WaveInRecorder m_Recorder;
private FifoStream m_Fifo = new FifoStream();
private byte[] m_PlayBuffer;
private byte[] m_RecBuffer;
private void Stop()
{
if (m_Player != null)
try
{
m_Player.Dispose();
}
finally
{
m_Player = null;
}
if (m_Recorder != null)
try
{
m_Recorder.Dispose();
}
finally
{
m_Recorder = null;
}
m_Fifo.Flush(); // clear all pending data
}
Please help me thanks and sorry for disturbing you again n again
With Best Regards Hardeep Singh Bhullar - If you have IDisposable fields/properties in a class, you generally should have the class itself also be IDisposable. Then implement the Dispose pattern as shown in http://www.bluebytesoftware.com/blog/PermaLink.aspx?guid=88e62cdf-5919-4ac7-bc33-20c06ae539ae In the Dispose(bool) method you do the cleanup as shown in "Simple Example w/out Finalize (C#)".


