Search code examples
c#wpfprogress-barbackgroundworker

Update WPF ProgressBar from invoked action


First, I should mention that I have already read this post and this and this, but none of them seem to fix my problem.

Simply explained, I have an unmanaged DLL which is called several times inside an invoked action, i.e.

var d = new List<string>();
var myData = new StringBuilder();

this.Dispatcher.Invoke(new Action(() =>
{
    myDLL.GetDataFromIndex(2, myData);
    d.Add(myData.ToString());

    myDLL.GetDataFromIndex(3, myData);
    d.Add(myData.ToString());

    myDLL.GetDataFromIndex(4, myData);
    d.Add(myData.ToString());

    //....
}
    ), System.Windows.Threading.DispatcherPriority.ContextIdle);

I want to show the progress of getting data by a ProgressBar. First, I tried to update the ProgressBar right after each DLL call by putting the following line after each d.Add(...)

pbStatus.Value = newValue;

It obviously didn't work and it also ruined myDLL calls. Then I learned that the ProgressBar must be updated through a BackgroundWorker, but I wasn't able to define a new BackgroundWorker inside the invoked action. Furthermore, the DLL calls take different times. For example, after GetDataFromIndex(2, ...) 20% of the process is completed, while the next indexes take 5 to 10 percent each. Now I have no idea how to update the ProgressBar right after each DLL call. Any hints or workarounds would be much appreciated due to my exhaustion from hours of pointless googling.


Solution

  • The dispatcher actions are beeing executed in the UI thread. So your code design is bad at that point allready that you are doing some external call there. Move your PINVOKING to a background task / thread, and call dispatcher.invoke just to set the progressbar progress from the background thread.

    As I promised, I created this github repository to demonstrate how to work with progressbar & background task ... it is WPF and I tried to follow the MVVM pattern.

    https://github.com/michalhainc/ProgressBarMVVMDemo