I have app where I'm using background worker to start some sequence. It needs to update GUI sometimes.
I have static class with references to some gui objects. In my logic I want to call method from this static class, with some parameters, there analyse it and update GUI. But I have "The calling thread cannot access this object because a different thread owns it." exception.
setting variable in first thread:
public static void SetCardHand(ref CardHand ch)
{
cardHand = ch;
}
Method called from background worker thread:
private static void SetCoveredCardsPlayer0(int cardsNumber)
{
if (cardsNumber < 1)
cardHand.imgCard1.Source = null;
else
cardHand.imgCard1.Source = (ImageSource)WindowManager.Instance.CardsGUI.CardsDictionary["T1"];
}
How to let this method change GUI?
It's not a window class. Its something like presenter.
Its a card game. I'm starting it in background worker and I need to update Image source(representing card) after each Deal.
You have to pass control back to the main thread prior to updating the UI. The BackgroundWorker makes this fairly easy.
When you create your BackgroundWorker
, set WorkerReportsProgress = true
.
Subscribe to the ProgressChanged
event, and place your logic that updates the UI into that event.
Within your DoWork
event, when you want to update the GUI, call myBackgroundWorker.ReportProgress(0, someObject)
, where "someObject" is the piece of data you want to act upon. In your case, probably the ImageSource
you're assigning to cardHand.imgCard1.Source
.
Inside the ReportProgress
event, you can access the object your passing via e.UserState
. You'll need to cast it back to an ImageSource
before using it.
You can keep your if (cardsNumber < 1)
logic inside the DoWork
event, but when you want to set the Source
to an ImageSource
(or null
), you'll want to pass that value to the ProgressChanged
event to actually update the UI element.