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

时间:2012-07-31 19:22:24

标签: c# .net wpf multithreading

我遇到一个问题,即使在查看有关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();

使用上面的当前实现,代码编译并运行,但任务完成后不会关闭Progress表单。有什么想法吗?

我也愿意接受其他想法来解决这个问题。也许我完全走错了路。

谢谢。

1 个答案:

答案 0 :(得分:7)

正如我在评论中提到的那样,当用户在Window_Closing事件中单击e.Cancel = true的关闭按钮时,我阻止关闭Progress窗口。这阻止了代码中的调用以关闭窗口。

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

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