如何在任务中关闭 WPF window

How to close WPF window inside of a Task

我需要运行一个任务来检查连接。

我的 windows 不应该在此检查期间被冻结。

所以我开始任务,并在任务结束时关闭我的 window。

但是这个 returns 一个例外:InvalidOperationException:'The calling thread cannot access this object because another thread owns it'.

像这样:

        private void Window_ContentRendered(object sender, System.EventArgs e)
        {
            Task.Run(() =>
            {
                ConnectionState = false;

                if (NetworkTools.CheckGlobalConnection() == (ConnectionStatus.NetworkConnectionSuccess, ConnectionStatus.ServerConnectionSuccess))
                {
                    ConnectionState = true;
                }

                this.Close();
            });
        }

如何在任务结束时关闭我的 window 而不会冻结它并且不会出现此异常? (我有一个无限旋转的进度条)

使用 Dispatcher 在唯一 UI 线程上排队 window 关闭逻辑。 就像是 Dispatcher.Invoke( () => { // close window here });

无论什么作为委托传递给 .Invoke(...),都会在 UI 线程上调用,因此有权访问所有 UI 元素。这是处理非 UI 线程中的 UI 突变的常见(也是唯一正确的)方法。

或者您可以只使用 async awaitTask.Run 将卸载并且等待将在当前 SynchronizationContext 上创建一个延续。反过来将控制权交还给 UI 并关闭正确的线程。

private async void Window_ContentRendered(object sender, System.EventArgs e)
{
   await Task.Run(() =>
         {
            ConnectionState = false;

            if (NetworkTools.CheckGlobalConnection() == (ConnectionStatus.NetworkConnectionSuccess, ConnectionStatus.ServerConnectionSuccess))
               ConnectionState = true;
         });

   this.Close();
}

另外如前所述,Calling ConfigureAwait(false) 在这种情况下不是正确的做法

作为替代方法,您可以使用 ContinueWith

private void Window_ContentRendered(object sender, System.EventArgs e)
    {
        Task.Run(() =>
         {
            // Your code

         }).ContinueWith((tsk) =>
         {
             this.Close();
         }, TaskScheduler.FromCurrentSynchronizationContext());
    }