WPF 和后台工作者以及调用线程必须是 STA

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21077626/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 10:29:52  来源:igfitidea点击:

WPF and background worker and the calling thread must be STA

c#.netwpf

提问by user1765862

I've implemented the solution from Stack Overflow question Implement progressbar in this simple WPF application.

我已经实现了 Stack Overflow 问题在这个简单的 WPF 应用程序中实现进度条的解决方案。

MainWindow has its own viewmodel. Inside that viewmodel I receive the user's input and consume the WCF service using a background worker. After WCF serves the data back, I'm trying to display it in a new window. This is where the error occurs:

MainWindow 有自己的视图模型。在该视图模型中,我接收用户的输入并使用后台工作人员使用 WCF 服务。在 WCF 提供数据后,我试图在新窗口中显示它。这是发生错误的地方:

The calling thread must be STA, because many UI components require this.

调用线程必须是 STA,因为许多 UI 组件都需要它。

I tried to put the [STAThread]attribute on the MainWindow code-behindas well as inside the MainWindowViewModel contructor. In both cases nothing changed.

我试图将该[STAThread]属性放在 MainWindow代码隐藏以及 MainWindowViewModel 构造函数内部。在这两种情况下都没有改变。

What am I missing?

我错过了什么?

UpdateAfter user clicks command in viewmodel call LoadData method

用户单击视图模型中的命令后更新调用 LoadData 方法

private void LoadData(string searchBy)
{
    IsBusy = true;
    BackgroundWorker worker = new BackgroundWorker();
    worker.DoWork += (o, ea) =>
    {
        switch (searchBy)
        {
            // WCF call to load data
        }
    }

    worker.RunWorkerCompleted += (o, ea) =>
    {
       IsBusy = false;
    };

    worker.RunWorkerAsync();

回答by theMayer

There are numerous duplicates of this issue on Stack Overflow. For example, this question.

Stack Overflow 上有很多关于此问题的重复项。例如,这个问题

Bottom line - any time you create UI components, you must use a single-threaded apartment (STA) thread. Background workers are not STA. Therefore, you cannot create UI components in background workers. You cannot update UI components from background workers. Background workers are designed to run in the background(big surprise there), possibly to crunch data and return a result later on.

底线 - 任何时候创建 UI 组件时,都必须使用单线程单元 (STA) 线程。后台工作者不是 STA。因此,您不能在后台工作人员中创建 UI 组件。您无法从后台工作人员更新 UI 组件。后台工作人员被设计为在后台运行(那里有很大的惊喜),可能会处理数据并稍后返回结果。

回答by qamar

I think you need to use Application.Current.Dispatcher.BeginInvoke(action). This is to update the UI from a background thread.

我认为你需要使用Application.Current.Dispatcher.BeginInvoke(action). 这是从后台线程更新 UI。