0

我一直在学习如何通过线程(BackgroundWorker和其他)来解决这个问题,以及如何保持 UI 响应。我设法做到了,但后来我意识到这不是我想要的。我实际上需要的只是在ProgressBar执行长时间操作时显示动画。(我不需要/不想更新 UI,因为在该操作中我正在导出所有图形表示并且绘图仪会不断更新)。

我考虑过在执行操作时弹出一个带有进度条的对话框。问题是我得到了这个异常:

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

关于这个有很多问题,答案是使用Dispatcher

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

以下是已完成的操作:

我正在使用现代 UI,有一个名为 ModernDialog 的对话框,它只是一个花哨的对话框:

  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();
    }
}

我知道我在那里混合东西,有线程和调度程序,但我不知道如何使用它们。

这是我如何调用此对话框:

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

如果我只使用 Dispatcher,则会显示对话框并且栏正在动画,但 MyLongMethod 不起作用(它在关闭对话框后开始)。

如果我使用线程,我会得到提到的异常。

我怎么解决这个问题?

(使用对话框的 PD 只是一个建议,如果进度条在 UI 中并且我在长方法开始/结束时切换可见性,我也会很高兴)

4

2 回答 2

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

这是错误的,因为您使用了 Invoke(),直到调用的方法完成运行它才会返回。这需要一段时间,ShowDialog() 是一个阻塞调用,直到用户关闭对话框才会完成。

简单的解决方法是改用 BeginInvoke()。

于 2013-08-31T12:47:24.810 回答
-1

假设ModernDialog是 WPF WindowShowDialog方法在关闭之前不会返回。Invoke在调用操作并返回之前也不会返回。您需要使用Show而不是,或者使用BeginInvoke而不是ShowDialog调用它。我会使用, 因为除非您等待用户通过单击对话框按钮做出响应,否则它实际上没有任何意义。InvokeShowShowDialog

于 2013-08-31T12:43:26.567 回答