C# 任务。延迟(N)系统。无效操作异常:';调用线程必须是STA,因为许多UI组件都需要它;

C# 任务。延迟(N)系统。无效操作异常:';调用线程必须是STA,因为许多UI组件都需要它;,c#,wpf,C#,Wpf,我想通过执行以下操作,从我的main窗口的ViewModel打开一个新的WPF窗口,延迟2秒: await Task.Delay(2000).ContinueWith(_ => { Restart wndRestart = new Restart(); wndRestart.Show(); }

我想通过执行以下操作,从我的
main窗口的ViewModel
打开一个新的
WPF窗口,延迟2秒:

await Task.Delay(2000).ContinueWith(_ =>
                    {
                        Restart wndRestart = new Restart();
                        wndRestart.Show();
                    }
                );
遗憾的是,我不断地得到:
System.invalidoOperationException:“调用线程必须是STA,因为许多UI组件都需要它。”


实际上我已经查过了,但即使重构了一个方法,我也无法使用
[STAThread]

您可以将自己的同步上下文传递给
ContinueWith
,告诉任务计划程序您的continuence应该在哪里运行:

await Task.Delay(2000).ContinueWith(_ =>
                {
                    Restart wndRestart = new Restart();
                    wndRestart.Show();
                },
                TaskScheduler.FromCurrentSynchronizationContext()
            );
否则,您将得到一个很可能不是STA的线程池线程


但是,对于WPF中的一次尝试在延迟后执行某些操作,也可以使用
调度程序

投票重新打开,因为链接的答案并没有真正解决此特定问题和所需的解决方案/解决方法。“链接的答案并没有真正解决此特定问题””“是的。或者至少,它解决了这个含糊不清的问题的一个例子。事实是,问题中没有足够的细节来知道问题出在哪里。如果发布的代码首先在UI线程中执行,那么根本不会发生异常。因此,修复它的一种方法是在UI线程中根据副本执行它。有很多其他情况可能会导致异常,但问题中没有任何证据表明这些情况适用。不要使用
任务。继续使用
。只需在
等待
后继续使用您的代码。只需澄清这一点:只能在UI线程上创建
窗口
。或者干脆不使用
任务。在此上下文中继续使用
。由于您等待
Task.Delay
,并且默认情况下
Task
配置为
ConfigureAwait(true)
,因此执行将在适当的线程(UI线程)上继续。如果以.NET 4.5及更高版本为目标,这是一个选项,是的。我曾经遇到过同样的问题,只是与.NET 4.0有关……基本上你是对的,但是.NET 4.0中没有
Task.Delay
<代码>等待
在此版本中也不可用。这意味着.NET>=4.5的问题。使用
Task.ContinueWith
,在简单的
wait
之后继续执行是没有意义的,除非您希望在工作线程上执行continuation,而OP的场景中显然不是这样。因此,降低配置continuation的线程池线程的开销似乎更明智。请注意,
Task.Delay
是一种纯异步方法,它不在线程池线程上运行。这一点很好。同意:-)