Setting Textbox.Text from BluetoothLEAdvertisementWatcher's received event throws an exception

fangfang wu 91 Reputation points Microsoft Employee
2019-10-30T06:39:53.99+00:00

I am creating a Bluetooth LE application in C# using a UWP project and have subscribed to get the Received event from the BluetoothLEAdvertisementWatcher.

I can see the data correctly using Debug.Writeline to the Output window, but as soon as I try to assign the same string data to a textbox, I receive a System.Exception message which is an unhandled error.

Here is the code:( I have put "Tester" as my string)

public sealed partial class MainPage : Page   
{  
    public MainPage()  
    {  
           this.InitializeComponent();  
           BluetoothLEAdvertisementWatcher watcher = new BluetoothLEAdvertisementWatcher();  
           watcher.Received += OnAdvertisementReceived;  
            …………  
     }  

    private void OnAdvertisementReceived(BluetoothLEAdvertisementWatcher watcher,    BluetoothLEAdvertisementReceivedEventArgs eventArgs)  
    {  
           …….   
           Debug.WriteLine("Tester");  
           if (Mytextbox != null)  
           {  
                Mytextbox.Text = "Tester";  
           }  
     }  
}  
      

I have tried using the Dispatcher object to access the textbox but I can't seem to get anything to work. Can someone help me out with a simple solution or point me in the right direction?
Thanks in advance!

Universal Windows Platform (UWP)
0 comments No comments
{count} votes

Accepted answer
  1. Roy Li - MSFT 31,551 Reputation points Microsoft Vendor
    2019-10-30T07:27:43.807+00:00

    Hello,

    Welcome to our Microsoft Q&A platform!

    Actually, it was a threading issue. The BluetoothLEAdvertisementWatcher's received event is generated on a different thread than the UI thread. As a result, you can't access the TextBox in the normal way as before. In UWP we recommend using Dispatcher.RunAsync to schedule work on the main UI thread.

    The following code shows the fix about this issue:

            public void NotifyUser(string strMessage)  
            {  
                // If called from the UI thread, then update immediately.  
                // Otherwise, schedule a task on the UI thread to perform the update.  
                if (Dispatcher.HasThreadAccess)  
                {  
                    UpdateStatus(strMessage);  
                }  
                else  
                {  
                    var task = Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => UpdateStatus(strMessage));  
                }  
            }  
      
    

    Thanks.

    1 person found this answer helpful.
    0 comments No comments

0 additional answers

Sort by: Most helpful