bugrasitemkar
bugrasitemkar

Reputation: 461

wpf c# background worker works when execution finished

I have a wpf application where I want to start a loading indicator before a task and end after task done. But the indicator starts after the task executes. What I am trying is as follows.

      private void RunAllScriptsChildwdwBtnOK_Click(object sender, RoutedEventArgs e)
    {
        worker.RunWorkerAsync(); // this supposed to start progress bar
        _RunAllScripts_Click();

    }

   private void worker_DoWork(object sender, DoWorkEventArgs e)
    {

        this.Dispatcher.Invoke(() =>
        {
            ... Start loading indicator
        });
    }

    private void worker_RunWorkerCompleted(object sender,
                                           RunWorkerCompletedEventArgs e)
    {
        ... End loading indicator
    }

But loading indicator starts and ends (as supposed in worker events) only after _RunAllScripts_Click(); method execution is complete. (I found that after unsubscribing from worker_RunWorkerCompleted event, progress bar starts and stays as is because no code to end it).

Also I want to add that, breakpoint hits worker_DoWork method before the execution, but UI updates after execution as I indicated above.

Thanks for all help you will be able to provide.

Upvotes: 0

Views: 583

Answers (3)

bugrasitemkar
bugrasitemkar

Reputation: 461

Dear kind people helping me about this subject, thank you all. This works for me, hope it works for all.

BackgroundWorker bwTestAll = new BackgroundWorker() { WorkerReportsProgress = true };

 bwTestAll.DoWork += new DoWorkEventHandler(TestAll);
        bwTestAll.RunWorkerCompleted += TestAll_RunWorkerCompleted;

//this is where I initialize my loading ring and other stuff and marshall background
//worker to do the main work
 Dispatcher.Invoke(new Action(() =>
                {
                    EnableLoading = true;
                    RunAllScriptsTest.IsEnabled = false;

                }), DispatcherPriority.ContextIdle);

                bwTestAll.RunWorkerAsync();


//this is my main work
  void TestAll(object sender, DoWorkEventArgs e)
    {
        presenter.RunAllScripts(true);
    }

//this is where I do my post-work stuff
 private void TestAll_RunWorkerCompleted(object sender,
                                   RunWorkerCompletedEventArgs e)
    {
        Dispatcher.Invoke(new Action(() =>
        {
            /
            EnableLoading = false;
            RunAllScriptsTest.IsEnabled = true;
            DbExecGrid = this.ExecutionResults;
            ShowOrHideExecGrid(this.EnableOrDisableGrid);

        }), DispatcherPriority.ContextIdle);
    } 

*Please Notice that Dispatcher with "DispatcherPriority.ContextIdle" works for me.

Upvotes: 0

d.moncada
d.moncada

Reputation: 17392

Using async/await will work. The await keyword will allow you to run work without affecting/blocking the UI thread (allowing message pumping to still occur). Once the work has finished, any code after the await keyword will execute.

Note that I have also wrapped the await work in an InvokeAsync call, as it appears that additional work you are doing required UI thread access.

private async void RunAllScriptsChildwdwBtnOK_Click(object sender, RoutedEventArgs e)
{
    //TODO  ... Start loading indicator

    await Task.Run(async ()=> 
    {
        await Application.Current.Dispatcher.InvokeAsync(()=>
        {
            _RunAllScripts_Click();
        });
    });

    //TODO  ... End loading indicator
}

Upvotes: 0

Dbl
Dbl

Reputation: 5893

If i was you i would use the async + await keyword for this

    private async void ButtonBase_OnClick(object sender, RoutedEventArgs e)
    {
        // this is where you would enable your indicator
        Button.IsEnabled = false;

        await Task.Run(
            () =>
            {
                // this is where you put your work, which should be executed in the background thread.
                Thread.Sleep(2000);
            });

        // this is where you would disable it
        Button.IsEnabled = true;
    }

Upvotes: 2

Related Questions