Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does BackgroundWorker_RunWorkerCompleted not update GUI?

I already searched the forum but no asked question fits to my problem I think ...

I use a BackgroundWorker to handle a very time consuming operation. After this operation finishes a button should be set to enabled so that the user can perform another operation.

I'm using WPF and I'm following the MVVM pattern, so I have no direct access to this button. I have to call a method in the BackgroundWorker_RunWorkerCompleted event handler which sets a Property, representing the buttons enabled-state, to true.

That all works fine except one thing: The button is only redrawn after I e.g. click into the window (or maximize the window, ...). Thats very annoying and took me the whole day to get rid of this behaviour but I can't find a solution ...

The BackgroundWorker_RunWorkerCompleted event handler looks like this:

    void fileLoadBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
        SetButtonToEnabled(); }

Has anyone any idea how to fix this issue?

Edit:

The button is bound to a command:

<Button Name="btnLoadTargetFile" Command="{Binding Path=LoadTargetCommand}" .../>

This command is a RelayCommand as Smith stated in his blog (http://msdn.microsoft.com/en-us/magazine/dd419663.aspx) and looks like this:

public RelayCommand LoadTargetCommand
    {
        get
        {
            if (loadTargetCommand == null)
            {
                loadTargetCommand = new RelayCommand(param => this.OnRequestLoadFile(BusinessLogic.CustomTypes.TreeType.Target), param => this.CanLoadTarget);
            }
            return loadTargetCommand;
        }
        set { loadTargetCommand = value; }
    }

this.CanLoadTarget is set to true by the SetButtonToEnabled(); method

Edit 2:

the following code 'works':

fileLoadBackgroundWorker.RunWorkerAsync(argumentList);
while(fileLoadBackgroundWorker.IsBusy)
  System.Windows.Forms.Application.DoEvents();
SetButtonToEnabled();

but that is some sort of really dangerous and ugly code ...

like image 444
lakai Avatar asked Oct 25 '22 22:10

lakai


1 Answers

Althought it doesnt explain your problem, you could try to add

System.Windows.Forms.Application.DoEvents();

or

Dispatcher.Invoke(new Action(delegate { }), DispatcherPriority.Background);

to the end of your SetButtonToEnabled function call (after you set the button Enabled to true). It looks like the backgroundworker is calling the Complete event, but the GUI is not refreshing.

Here is a complete example using the Backgroundworker in WPF. You might want to take a look at it and make sure you stuff looks the same.

You could also take a look at Asynchronous Threading with Background Worker Object. This is a good example of using the Dispatcher and the Backgroundworker

The WPF Threading Model is another great source to check out.

like image 147
SwDevMan81 Avatar answered Nov 08 '22 14:11

SwDevMan81