.NET Framework Developer Center > .NET Development Forums > Windows Presentation Foundation (WPF) > Error:The calling thread cannot access the object because different thread owns it :WPF Browser App
Ask a questionAsk a question
 

AnswerError:The calling thread cannot access the object because different thread owns it :WPF Browser App

  • Tuesday, November 03, 2009 11:24 AMhardeepbhullar Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    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

  • Tuesday, November 03, 2009 11:34 AMRahul P Nath Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    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
    •  
  • Tuesday, November 03, 2009 11:34 AMkesavan_k Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    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
  • Tuesday, November 03, 2009 11:40 AMAdham El-Wakeel Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     AnswerHas Code

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

     this.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() =>
                {
                   //Your Code Goes Here
    
                }));
    
    Good Luck

    p.s. you gonna need to use system.windows.threading

  • Wednesday, November 04, 2009 6:03 AMHua ChenMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     AnswerHas Code
    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.
     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)));
                }));
            }
    
      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);
    
                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);
            }
    
      We can also use DispatcherPriority.Send priority.

      Thanks.

    Please mark the replies as answers if they help and unmark them if they provide no help
  • Wednesday, November 04, 2009 8:07 AMDanielRose Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     AnswerHas Code
    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:
    string sendingPortText = (string) this.Dispatcher.Invoke(new Func<string>(() => this.txtSendingPort.Text;));
    
    Kind regards,
    Daniel Rose
  • Wednesday, November 04, 2009 1:43 PMDanielRose Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer

    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.

All Replies

  • Tuesday, November 03, 2009 11:34 AMRahul P Nath Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    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
    •  
  • Tuesday, November 03, 2009 11:34 AMkesavan_k Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    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
  • Tuesday, November 03, 2009 11:40 AMAdham El-Wakeel Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     AnswerHas Code

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

     this.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() =>
                {
                   //Your Code Goes Here
    
                }));
    
    Good Luck

    p.s. you gonna need to use system.windows.threading

  • Tuesday, November 03, 2009 1:55 PMhardeepbhullar Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    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
  • Wednesday, November 04, 2009 6:03 AMHua ChenMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     AnswerHas Code
    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.
     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)));
                }));
            }
    
      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);
    
                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);
            }
    
      We can also use DispatcherPriority.Send priority.

      Thanks.

    Please mark the replies as answers if they help and unmark them if they provide no help
  • Wednesday, November 04, 2009 7:23 AMhardeepbhullar Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    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
  • Wednesday, November 04, 2009 8:07 AMDanielRose Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     AnswerHas Code
    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:
    string sendingPortText = (string) this.Dispatcher.Invoke(new Func<string>(() => this.txtSendingPort.Text;));
    
    Kind regards,
    Daniel Rose
  • Wednesday, November 04, 2009 1:36 PMhardeepbhullar Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    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
  • Wednesday, November 04, 2009 1:43 PMDanielRose Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer

    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.

  • Thursday, November 05, 2009 8:26 AMhardeepbhullar Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    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
  • Friday, November 06, 2009 8:42 AMDanielRose Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    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#)".