使用Dispatcher.Invoke在WPF中从不同的线程关闭窗口

5

我有一个问题,即使查看了各种与Dispatcher.Invoke相关的信息,仍然无法解决。

有一个MainWindow创建了一个任务,并启动该任务,然后打开一个进度窗口。当任务完成时,我需要关闭进度窗口。这是我的代码:

private void Button_Click(object sender, RoutedEventArgs e)
    {
        Task task = new Task(_vm.WriteToDB);
        task.ContinueWith(ExceptionHandler, TaskContinuationOptions.OnlyOnFaulted);
        task.ContinueWith(RanToCompletion, TaskContinuationOptions.OnlyOnRanToCompletion);
        task.Start();

        _frmProgress = new Progress(task);
        _frmProgress.DataContext = _vm;
        _vm.ProgressText = "Connecting to update server...";
        _frmProgress.ShowDialog();
    }

    public void RanToCompletion(Task task)
    {
        Progress.FormCloseDelegate FormCloseDelegate = new Progress.FormCloseDelegate(_frmProgress.Close);

        if (_frmProgress.Dispatcher.CheckAccess())
            _frmProgress.Close();
        else
            _frmProgress.Dispatcher.Invoke(DispatcherPriority.Normal, FormCloseDelegate);
    }

FormCloseDelegate在进度窗口中定义:

public delegate void FormCloseDelegate();

使用以上当前的实现方式,代码可以编译并运行,但任务完成后进度表单没有关闭。有什么想法吗?

我也很乐意接受其他解决方案。也许我本来就走了错误的道路。

谢谢!


你尝试过使用BeginInvoke而不是Invoke吗? - Colin Smith
是的,使用BeginInvoke也会得到相同的结果。 - ChrisO
尝试过使用DispatcherPriority.Send吗?它可能被排队,直到您的进度对话框退出才被分派。 - Colin Smith
谢谢您的建议。我刚尝试了DispatcherPriority.Send,但没有成功。 - ChrisO
它实际上是否调用了你的RanToCompletion方法? - Colin Smith
显示剩余3条评论
1个回答

9

如我在评论中提到的那样,当用户在Window_Closing事件中使用e.Cancel=true点击关闭按钮时,我会阻止进度窗口的关闭。这也阻止了代码中关闭窗口的调用。

在意识到我根本不需要自定义委托之后,我更新了RanToCompletion方法:

public void RanToCompletion(Task task)
    {
        if (_frmProgress.Dispatcher.CheckAccess())
            _frmProgress.Close();
        else
            _frmProgress.Dispatcher.Invoke(DispatcherPriority.Normal, new ThreadStart(_frmProgress.Close));
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接