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
是一种纯异步方法,它不在线程池线程上运行。这一点很好。同意:-)