0

I am using a BackgroundWorker to monitor if a bit has flipped on an external device every couple of seconds. I then want it to call a function that is to be run on the main UI thread, but is instead being run on the same thread as the BackgroundWorker. This is a problem because I am getting errors about the application interface being marshaled on a different thread.

Currently when I call the function from the BackgroundWorker thread it is be computed on the same thread as the BackgroundWorker.

private void Task1()
{
    //Function does work before calling backgroundworker
    BackGroundWorker.RunWorkerAsync();
}

private async void BackGroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
    //Monitor for bit being flipped on external device
    Task2();
}

private void Task2()
{
    //Work to be completed after the bit has been flipped
}

I'm expecting that once the bit has been detected to have flipped, the BackgroundWorker thread calls the function to be completed on the main UI thread.

What has actually been happening is that I get the following error because the function is being run on the same thread as the BackgroundWorker:

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

Peter Duniho
  • 68,759
  • 7
  • 102
  • 136
Logan
  • 13
  • 3
  • 1
    The BackgroundWorker has an `ProgressChanged` that is raised via the worker's `ReportProgress` method and invoked on the UI thread. You'd need to set `worker.ReportsProgress` property to `true`. – René Vogt Aug 21 '19 at 16:02
  • 1
    I'm not familiar with `uwp`, but if you're periodically checking something then updating the UI, would something like [`DispatcherTimer`](https://learn.microsoft.com/en-us/uwp/api/windows.ui.xaml.dispatchertimer) be a better choice than `BackgroundWorker`? – Joshua Robinson Aug 21 '19 at 16:43
  • 1
    You can explicitly marshal the call to the correct thread using the advice found by searching on your error message, as in the marked duplicate. However, the other comments are correct: you can get `BackgroundWorker` to do this implicitly by using the `ProgressChanged` event, or you could just use a timing mechanism that itself implicitly runs in the UI thread. You could even just use a simple `async` method with a loop, a call to `await Task.Delay()` for timing, and then put the code to update the UI in the loop. Any of those four approaches are viable. – Peter Duniho Aug 21 '19 at 16:48
  • Thank you @PeterDuniho for the answer it was very helpful. I ended up using the `await Dispatcher.RunAsync` found on the link to the previous version of the question. Here is a link to the answer if anyone else needs it: https://stackoverflow.com/a/27698035/11777406 – Logan Aug 21 '19 at 17:28

0 Answers0