【问题标题】:Trouble Awaiting Task in UI在 UI 中等待任务时遇到问题
【发布时间】:2019-03-08 13:37:41
【问题描述】:

在我的 WPF 应用程序后面的 MainWindow 代码中运行的以下方法正在产生一个有据可查的 StackOverflow 错误:

        async void LDAPLookupButton_Click(object sender, RoutedEventArgs e)
        {
            input = LDAPInputFileLocationTextBox_Value.Text;

            LDAPProgress.Visibility = Visibility.Visible;
            await Task.Run(() => LDAPLookups.ExportToCSV(input));
            LDAPProgress.Visibility = Visibility.Hidden;
        }

这会导致错误:

调用线程必须是 STA,因为很多 UI 组件都需要这个。

根据推荐的指导调整方法允许应用程序运行,但正如预期的那样,在执行 Dispatcher 操作期间 UI 被阻止:

            async void LDAPLookupButton_Click(object sender, RoutedEventArgs e)
            {
                input = LDAPInputFileLocationTextBox_Value.Text;

                LDAPProgress.Visibility = Visibility.Visible;

                Dispatcher.Invoke(() =>
                {
                     LDAPLookups.ExportToCSV(input);
                });

                LDAPProgress.Visibility = Visibility.Hidden;
            }

此时我有两个问题:

  1. 为什么在 LDAPLookups.ExportToCSV 方法未对 UI 进行更新时调用“调用线程必须是 STA...”错误?该方法用完另一个类,只是在本地机器上创建了一个 .csv。

  2. 如何在不阻塞 UI 的情况下允许它运行?

【问题讨论】:

  • 我看到此错误发生的唯一原因是ExportToCSV(请记住它现在在工作线程中运行)正在访问 UI。是吗?使用Dispatcher.Invoke* 对async/await 来说毫无意义,尤其是当您已经处于 UI 回调中时
  • 啊。我找到了一行,我在 LDAPLookups 类(静态 MainWindow main = new MainWindow();)中创建了 MainWindow 的一个实例。我删除了它并且不再遇到错误。奇怪的是,简单地创建 MainWindow 的一个实例,但不操作任何属性或控件就足以产生该错误。
  • 好的,我已经发布了我的评论作为答案

标签: c# .net wpf


【解决方案1】:

上述问题下方的评论摘要


我可以看到此错误发生的唯一原因是ExportToCSV(请记住它现在在 工作线程 中运行,并且工作线程可能无法直接访问 UI)正在访问 UI .是吗?

另外,使用Dispatcher.Invoke* 对async/await 来说毫无意义,尤其是当您已经处于 UI 回调中时。

一定要检查相关代码。

【讨论】:

    【解决方案2】:

    第二个问题使用 Dispatcher.BeginInvoke() 将被异步调用。

    【讨论】:

    • 这确实使它异步,但我需要等待方法的完成。如果我在 Dispatcher.BeginInvoke 之前添加等待,我将返回阻塞 UI。
    • 虽然是这样,但 OP 正在使用 async/await 并且已经在 UI 线程上。问题出在工作线程中
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-28
    • 2014-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多