0

I've been learning about how this issue is confronted via Threads (BackgroundWorker and others) and how to keep the UI responsive. I've managed to do so but then I realized that is not what I want. What I need actually is just to display an animating ProgressBar while a long operation is performed. (I don't need/want to update the UI because in that operation I'm exporting all graphical representation and the plotter is updated constantly).

I have thought about a Dialog popping-up with the progress bar while the operation is being performed. The problem is that I get this exception:

The calling thread cannot access this object because a different thread owns it 

There are plenty of questions about this and the answer is to use Dispatcher:

 Dispatcher.CurrentDispatcher.Invoke(() => myOperation(), DispatcherPriority.Normal); 

Here is what've done:

I'm using Modern UI, there is a Dialog called ModernDialog, it's just a fancy dialog:

 class DialogProgress { public ModernDialog progressDlg = new ModernDialog(); public DialogProgress() { ProgressBar bar = new ProgressBar(); bar.IsIndeterminate = true; bar.Width = 150; StackPanel content = new StackPanel(); content.Children.Add(bar); progresoDlg.Content = content ; //Thread paralel = new Thread(() => myOperation()); //paralel.SetApartmentState(ApartmentState.STA); //paralel.Start(); Dispatcher.CurrentDispatcher.Invoke(() => myOperation(), DispatcherPriority.Normal); } void myOperation() { progresoDlg.ShowDialog(); } } 

I know I'm mixing stuff there, there are Threads and Dispatcher, but I can't figure out how to use them.

Here is how I call this dialog:

public void MyLongMethod() { DialogProgress progress = new DialogProgress(); } 

If I use only Dispatcher, the dialog shows up and the bar is being animated but MyLongMethod is not working (it starts after closing the dialog).

If I use Threads I get the mentioned exception.

How can I solve this problem?

(P.D. using a dialog Is only a suggestion, I would be happy too if the progress bar is in the UI and I switch the visibility when the long method starts/ends)

1
  • Try using a delegate Commented Aug 31, 2013 at 12:26

2 Answers 2

2
 Dispatcher.CurrentDispatcher.Invoke(...); 

This goes wrong because you used Invoke(), it will not return until the invoked method finished running. Which will take a while, ShowDialog() is a blocking call that doesn't complete until the user closes the dialog.

The simple workaround is to use BeginInvoke() instead.

Sign up to request clarification or add additional context in comments.

5 Comments

If I use BeginInvoke() I get this error. Cannot convert lambda expression to type 'System.Delegate' because it is not a delegate type How could I convert the original method to a delegate type?
Use BeginInvoke(new Action(() => stuff));
Thanks, I've tried this but the dialog it's not in a separate thread and the progress bar is not being animated. Is there a way to "force" the dispatcher to be in a new thread?
It is not in a separate thread, it runs on the UI thread. Which is why you can see the dialog and WPF doesn't bitch at you for getting it wrong. I can't guess why the progress bar doesn't animate, your question has no hints whatsoever what you might do to get it to animate. Using a BackgroundWorker and implementing the ProgressChanged event is the boilerplate solution.
@Sturm You still must create your own thread to run the long operation. The dispatcher can be called from that other thread in order to schedule an update on the UI thread.
-1

Assuming ModernDialog is a WPF Window, the ShowDialog method does not return until it's closed. Invoke also doesn't return until the operation is called and returns. You need to either use Show instead of ShowDialog, or call it with BeginInvoke instead of Invoke. I would use Show, because ShowDialog doesn't really make sense unless you are waiting for the user to respond by clicking a dialog button.

2 Comments

has it got anything to do with ProgressBar ?
@Kyle No, the fact that a progress bar is involved is irrelevant to the issue. Why was this downvoted?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.