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?
(PD 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)
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.
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.