0

I am very new to C# and Azure IoT. Perhaps the problem I have is very simple to solve. I would like to update the an UI Element by invoking a method from the cloud. But I am getting the following Error:

The application called an interface that was marshalled for a different thread. (Exception from HRESULT: 0x8001010E (RPC_E_WRONG_THREAD))

I know t has something to do with the fact that the UI is running in another thread. but I didn´t find any solution.

Here the code

public sealed partial class MainPage : Page
{

    DeviceClient deviceClient;

    public MainPage()
    {
        this.InitializeComponent();
        deviceClient = DeviceClient.CreateFromConnectionString(GlobalConstant.DEVICE_CONNECTION_STRING, TransportType.Mqtt);
        deviceClient.SetMethodHandlerAsync("UpdateTextfield", UpdateTextfield, null);
    }

    private void updateTextField ()
    {
        IncomingMessage.Text = "Update";
    }

    private Task<MethodResponse> UpdateTextfield(MethodRequest methodRequest, object userContext)
    {
        updateTextField();
        string result = "{\"result\":\"Executed direct method: " + methodRequest.Name + "\"}";
        return Task.FromResult(new MethodResponse(Encoding.UTF8.GetBytes(result), 200));
    }
}
  • Possible duplicate of [How do I update the GUI from another thread?](https://stackoverflow.com/questions/661561/how-do-i-update-the-gui-from-another-thread) – Peter Bons Jun 06 '18 at 09:58
  • No operating system allows you to modify the UI from another thread. In a XAML/WPF/UWP application that uses MVVM or simply data binding you don't need to anyway. You *don't* modify the control directly. The control binds to a property and gets updated when the property is modified and the PropertyChanged event is raised – Panagiotis Kanavos Jun 06 '18 at 11:00
  • You can use the `IProgress` interface to report progress or any other message from a background thread anyway, as shown in [Enabling Progress and Cancellation in Async APIs](Enabling Progress and Cancellation in Async APIs) – Panagiotis Kanavos Jun 06 '18 at 11:02
  • @quallenbezwinger Does the reply solved your issue or still have some problem? – Rita Han Jun 27 '18 at 07:20

1 Answers1

0

The process that you are calling the: IncomingMessage.Text = "Update"; is happening on a thread that is non-UI threads. You need to marshal the thread from the current executing thread to the UI thread.

Windows.UI.Core.CoreDispatcher can be used to this. Here is an example:

    using Windows.ApplicationModel.Core;

    private async void updateTextField ()
    {
        await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, ()=>{
            IncomingMessage.Text = "Update";
        });    
    }

Cross reference: "Run code on UI thread in WinRT"

Rita Han
  • 9,574
  • 1
  • 11
  • 24
  • I'm not familiar with WPF/UWP, but is it better to put the assignment of `dispatcher` in the `async void updateTextField` method? `GetForCurrentThread` here we need to make sure the `current` is really the one we want. – Cheng Chen Jun 07 '18 at 02:21
  • @DannyChen You're right. Thanks. I update my answer. – Rita Han Jun 07 '18 at 05:59