【问题标题】:How to close WPF window inside of a Task如何关闭任务内的 WPF 窗口
【发布时间】:2019-04-09 09:35:03
【问题描述】:

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

在此检查期间不应冻结我的窗户。

所以我启动任务,并在任务结束时关闭我的窗口。

但这会返回一个异常:InvalidOperationException:'调用线程无法访问这个对象,因为另一个线程拥有它'。

像这样:

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

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

                this.Close();
            });
        }

如何在任务结束时关闭我的窗口而不冻结它并且没有这个异常? (我有一个无限旋转的进度条)

【问题讨论】:

  • 调用它? UI 上的任何内容都必须从线程中调用
  • 使用应用程序线程作为代理关闭窗口

标签: c# wpf task freeze


【解决方案1】:

或者你可以只使用 async await。 Task.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) 在这种情况下不是正确的做法

【讨论】:

  • 等待一些启示
  • 我投了反对票,因为它太特别了,没有提供任何关于 Dispatchering 的见解。至少,提供一些 cmets 来解释这通常不是实现所需行为的正确方法。
  • 顺便说一句,您也可以指定.ConfigureAwait(false) 会导致问题。
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

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

    private void Window_ContentRendered(object sender, System.EventArgs e)
        {
            Task.Run(() =>
             {
                // Your code
    
             }).ContinueWith((tsk) =>
             {
                 this.Close();
             }, TaskScheduler.FromCurrentSynchronizationContext());
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-09
      • 2013-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-20
      • 2011-09-26
      • 1970-01-01
      相关资源
      最近更新 更多