A.Shoman
A.Shoman

Reputation: 3085

Updating UI using dispatcher.beginInvoke

So, I am reading a message through the mobile Bluetooth and I am trying to update the UI with the data I received.

Calling another method, the 'update' method as following

try
{
   await update();
}
catch (Exception e)
{
     Debug.WriteLine("Exception has been called");
     Debug.WriteLine("Type| " + e.GetType());
     Debug.WriteLine("Inner Exception| " + e.InnerException);
     Debug.WriteLine("Message| " + e.Message);
}

and the update method goes as followes

public async Task<String> update()
{
    string[] sMsg = msg.Split(new Char[]{'\n'});

    string[] finalmsg = sMsg[0].Split(new Char[]{':'});

    if ((finalmsg.Length != 8 && sMsg[0] == msg) || sMsg.Length < 2)
    { // not finished reading 
        //Debug.WriteLine("\n\n--skip as the size is : " + finalmsg.Length);
        return null;
    }

    msg = msg.Substring(sMsg[0].Length+2,msg.Length-(sMsg[0].Length+2));
    if (finalmsg.Length >= 8){

        System.Threading.Thread thread = new System.Threading.Thread(
            new System.Threading.ThreadStart(
                   delegate()
                   {
                     Dispatcher.BeginInvoke(delegate()
                     {
                        string[] fm = finalmsg;
                        RX.Text = finalmsg[0];
                        RY.Text = finalmsg[1];
                        LX.Text = finalmsg[2];
                        LY.Text = finalmsg[3];
                        RF1.Text = finalmsg[4];
                        RF2.Text = finalmsg[5];
                        LF1.Text = finalmsg[6];
                        LF2.Text = finalmsg[7];
                     });
                  }
            ));

        thread.Start();

        if(!thread.IsAlive)
            thread.Abort();
        }

    return finalmsg[0];
    }            
}

So the problem I am facing now is that, updating the UI in the body of Dispatcher.BeginInvoke works for 20 seconds and then an exception fires as following

exception has been thrown by the target of an invocation

The exception is fired in the App.xaml, Application_UnhandledException method That means the exception is not handled in the code, and I was not able to catch even with try clause.

What I am thinking now is I am doing a mistake because I don't really understand how dispatcher.beginInvoke

So could you please advice of what may went wrong here ? Thanks in advance.

Edit: To elaborate more this is the stack trace of the exception I got

Stack Trace:

  at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
  at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
  at System.Reflection.RuntimeMethodInfo.UnsafeInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
  at System.Delegate.DynamicInvokeImpl(Object[] args)
  at System.Windows.Threading.DispatcherOperation.Invoke()
  at System.Windows.Threading.Dispatcher.Dispatch(DispatcherPriority priority)
  at System.Windows.Threading.Dispatcher.OnInvoke(Object context)
  at System.Windows.Hosting.CallbackCookie.Invoke(Object[] args)
  at System.Windows.RuntimeHost.ManagedHost.InvokeDelegate(IntPtr pHandle, Int32 nParamCount, ScriptParam* pParams, ScriptParam* pResult)

Upvotes: 0

Views: 1682

Answers (1)

vITs
vITs

Reputation: 1560

The UI updation part needs to be done on Dispatcher thread if there is another processing going on which may conflict to your thread,So modify your code like this:

public string update()
        {
            string[] sMsg = msg.Split(new Char[]{'\n'});

            string[] finalmsg = sMsg[0].Split(new Char[]{':'});

            if ((finalmsg.Length != 8 && sMsg[0] == msg) || sMsg.Length < 2)
            { // not finished reading 
                //Debug.WriteLine("\n\n--skip as the size is : " + finalmsg.Length);
                return null;
            }

            msg = msg.Substring(sMsg[0].Length+2,msg.Length-(sMsg[0].Length+2));
            if (finalmsg.Length >= 8){

                Dispatcher.BeginInvoke(delegate()
                    {
                        string[] fm = finalmsg;
                        RX.Text = finalmsg[0];
                        RY.Text = finalmsg[1];
                        LX.Text = finalmsg[2];
                        LY.Text = finalmsg[3];
                        RF1.Text = finalmsg[4];
                        RF2.Text = finalmsg[5];
                        LF1.Text = finalmsg[6];
                        LF2.Text = finalmsg[7];
                    });                             
            }

            return finalmsg[0];
        }

Just make sure modify your code such that UI updation should take place in Dispatcher.No need of putting Dispatcher in other thread.

Upvotes: 1

Related Questions