Search code examples
c#multithreadingbackgroundworker

BackgroundWorker, update gui, static method


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?

edit

It's not a window class. Its something like presenter.

edit2

Its a card game. I'm starting it in background worker and I need to update Image source(representing card) after each Deal.


Solution

  • You have to pass control back to the main thread prior to updating the UI. The BackgroundWorker makes this fairly easy.

    1. When you create your BackgroundWorker, set WorkerReportsProgress = true.

    2. Subscribe to the ProgressChanged event, and place your logic that updates the UI into that event.

    3. 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.

    4. 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.