I'm writing an app in C#/WPF (.Net framework 4.0). The one thing I am having a problem with is how to update controls, if possible, while the app is very busy. I think I'm just flailing about trying things I find on the web to make it work (and on rare occasions it does). The app has four classes, a main window class, a Worker1 class and a Worker2 class and a static ExtensionMethods class. Worker2 is called from Worker1 and does most of the work. When it runs the CPU is at 100% (core at 100%, system has four cores). (All are in the same namespace.)
public static class ExtensionMethods
{
private static Action EmptyDelegate = delegate() { };
public static void Refresh(this UIElement uiElement)
{
uiElement.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Render, EmptyDelegate);
}
}
The main window calls a top level function in Worker1, which goes through some setup and then starts the long process, which goes something like this:
MainWindow mainWindow = App.Current.MainWindow as MainWindow;
mainWindow.dispatcher_UpdateProgressBarMaximum(maxValue);
int count=0;
Worker2 worker2 = new Worker2();
while (bytesRead =(readData() !=0) {
count++;
worker2.doWork();
mainWindow.dispatcher_UpdateProgressBar(count);
}
In the mainWindow class is:
dispatcher_UpdateProgressBar(int Value)
{
Dispatcher.BeginInvoke(new Action(() => myProgressBar.Value = value), null);
myProgressBar.Refresh();
}
(I have also tried it with: myProgressBar.Dispatcher.Begin...etc.
but neither matter too much. With small files where there are 2 or 3 reads I can see the progress bar getting updated. But with large files, no update until the end. This happens also for some label controls in which I display some status information. After the entire work is completed I optionally display a messagebox of what was done. For the labels, when I display the messagebox, the labels are updated. The app may work on many files one after the other.
I've thought about using a background thread but not sure how to do it. That is, the worker2.doWork() section is very intensive but if that's on it's own thread the the mainWindow.dispatcher_Update...will be called immediately after the thread begins and there's nothing to stop the next read from happening, right?
Perhaps it's impossible the way I've coded it. IF I used a Backgroundworker, would the class be instantiated in the Main Window or Worker1? Even a pointer or two would be great.