0

我正在使用 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();

我该如何解决这个问题?

提前致谢。

4

3 回答 3

3

原因是我们新创建的线程没有启用支持 WPF 窗口基础结构。特别是,它不支持 Windows 消息泵,您必须为新创建的窗口运行单独的调度程序。这是此示例

于 2012-04-23T09:15:52.153 回答
2

WPF 要求 thred 是 STA 类型,因此如果您希望 DisplayFormThread 由 STA thead 调用,您必须执行以下操作:

Thread newThread = new Thread(new ThreadStart(DisplayFormThread));
newThread.SetApartmentState(ApartmentState.STA);
newThread.Start();

STAThread 指的是“单线程公寓”,指的是当前(主)线程使用的线程模型。基本上,通过 [STAThread] 声明,其他应用程序将在向您发送数据时知道您的线程策略是什么。STA 模型是 Windows 线程/应用程序最常见的线程模型。您可以在此处阅读有关公寓状态的更多信息。

于 2012-04-23T08:13:43.103 回答
0

UI 对象必须在单线程单元(sta)中声明,并且对于每个 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 线程之间的数据共享。

于 2020-05-20T14:08:58.703 回答