我正在使用WPF。我使用Dispatcher在主xaml窗口中运行一个线程进程。
然后我打开另一个WPF以显示显示3D图像的结果时出现此错误:
{“调用线程必须是STA,因为许多UI组件都需要 此。“}
这是我开始一个新窗口的方式:
void DisplayFormThread()
{
IResult result = _mainWindow.GetResult();
ResultView resultView = new ResultView (result);
resultView.Show();
}
我试图通过在stackoverflow上的一些帖子中添加它来解决这个问题,但它没有帮助:
ThreadStart start = delegate()
{
DispatcherOperation op = Dispatcher.CurrentDispatcher.BeginInvoke(
new delegateNewWindow(DisplayFormThread), DispatcherPriority.Background);
DispatcherOperationStatus status = op.Status;
while (status != DispatcherOperationStatus.Completed)
{
status = op.Wait(TimeSpan.FromMilliseconds(1000));
if (status == DispatcherOperationStatus.Aborted)
{
// Alert Someone
}
}
};
// Create the thread and kick it started!
Thread thread = new Thread(start);
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
我该如何解决这个问题?
提前致谢。
答案 0 :(得分:3)
原因是我们新创建的线程未启用支持WPF窗口基础结构。特别是,它不支持Windows消息抽取,您必须为新创建的窗口运行单独的调度程序。 Here is sample for this
答案 1 :(得分:2)
WPF要求thred是STA类型,所以如果你想让STA调用DisplayFormThread,你必须做这样的事情:
Thread newThread = new Thread(new ThreadStart(DisplayFormThread));
newThread.SetApartmentState(ApartmentState.STA);
newThread.Start();
STAThread是指“Single-Threaded Apartments”,它指的是当前(主要)线程使用的线程模型。基本上,使用[STAThread]声明,其他应用程序将在发送数据时知道您的线程策略是什么。 STA模型是Windows线程/应用程序最常用的线程模型。您可以阅读有关Apartment State here的更多信息。
答案 2 :(得分:0)
UI对象必须在单线程单元中声明,并且对于每个STA线程,必须创建一个新的调度程序。
您必须在线程启动的动作参数内调用Dispatcher.Run()
ThreadStart start = delegate() {
DispatcherOperation op = Dispatcher.CurrentDispatcher.BeginInvoke(
new delegateNewWindow(DisplayFormThread), DispatcherPriority.Background);
DispatcherOperationStatus status = op.Status;
while (status != DispatcherOperationStatus.Completed) {
status = op.Wait(TimeSpan.FromMilliseconds(1000));
if (status == DispatcherOperationStatus.Aborted) {
// Alert Someone
}
}
Dispatcher.Run();
};
// Create the thread and kick it started!
Thread thread = new Thread(start);
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
WPF UI线程需要一个调度程序,因为调度程序管理多个UI线程之间的数据共享。