WPF - 尝试在任务中打开新窗口但收到“调用线程必须为STA异常”

4

这是我的第一篇帖子,如果我犯了错误,请原谅。

我有一个返回字符串的任务。在该任务中,我想打开一个新窗口,让用户输入代码。一旦输入代码并关闭窗口,任务将返回该代码。

我的代码如下:

 public Task<string> GetLoginCode()
        {

            return Task.Run(() =>
            {
                CodeRequestView view = new CodeRequestView();
                CodeRequestViewModel viewModel = new CodeRequestViewModel();
                view.ShowDialog();
                return viewModel.Code;
            });

        }

我遇到的问题是在运行项目时,在CodeRequestView.xmal.cs文件的构造函数处收到一个“调用线程必须是STA,因为许多UI组件需要这样”的异常。请帮我解决这个问题,感谢!

2个回答

4

由于您正在从非UI线程调用UI相关的内容,因此可以使用像Dispatcher这样的UI线程。

  public Task<string> GetLoginCode()
            {

                return Task.Run(() =>
                {
                    CodeRequestViewModel viewModel = new CodeRequestViewModel();
                    Application.Current.Dispatcher.Invoke(delegate 
                    {
                        CodeRequestView view = new CodeRequestView();
                        view.ShowDialog();
                    });
                    return viewModel.Code;
                });
            }

2
WPF窗口和控件需要在STA线程上运行,以维护其公寓状态。Task.Run()使用线程池,这些线程池被定义为MTA,它们不允许实例化一个必须在STA线程上的Window子类对象。
您需要手动创建一个新线程,并将其公寓状态设置为STA,在使用它创建新窗口对象之前。由于您没有显示完整代码,所以我不知道为什么它需要返回一个Task对象而不是一个string对象。如果您希望它异步运行(可等待),则原始实现使用Task.Run()将在另一个线程(从线程池)上运行并立即返回给调用者。
无论如何,这是一个示例:
public string GetLoginCode()
{
    string retVal;
    Thread viewThread = new Thread(() =>
    {
        CodeRequestView view = new CodeRequestView();
        CodeRequestViewModel viewModel = new CodeRequestViewModel();
        view.ShowDialog();
        retVal = viewModel.Code;
        });
    }
    viewThread.SetApartmentState(ApartmentState.STA);
    viewThread.Start();

    return retVal;
}

虽然我从未尝试过,但我不确定返回值是否会导致同步问题。


1
你可能想提醒楼主,在GUI应用程序中,虽然在技术上可以实现两个STA线程,但这种做法并不被推荐。首先,我们必须问一下,为什么需要这样做呢? - user585968
我确实同意很多人在可能的情况下倾向于创建新线程(或从线程池中获取),这让他们觉得应用程序更加响应。大多数情况下,改进非常微小,但却给他们带来了十倍于多线程带来的麻烦。楼主确实需要问自己为什么需要这样做。记住,最优雅的解决方案就是简单的解决方案。 - Jai

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接