【问题标题】:creating a UI in background thread WPF?在后台线程 WPF 中创建 UI?
【发布时间】:2011-12-29 11:53:43
【问题描述】:

我尝试了以下操作:

var task = new Task(() =>
    {
       for (int i=0; i<10; i++) {
          //Create new Grid HERE
          // Add Table with some dynamic data here..
          // print the above Grid here.
        }

    });

task.ContinueWith((previousTask) =>
    {
        label.Content = printerStatus(); // will return "Out of Paper", "printing", "Paper jam", etc.
    },
    TaskScheduler.FromCurrentSynchronizationContext());

label.Content = "Sending to printer";

返回如下错误:调用线程必须是STA,因为很多UI组件都需要这个..

尝试创建新的 UI 对象 Grid 时发生错误。

我该如何解决这个问题?让我知道是否还有其他方法!

【问题讨论】:

    标签: c# .net wpf multithreading


    【解决方案1】:

    任务使用 MTA 中的线程池线程。

    如果您想要一个后台 STA 线程,您必须自己创建一个并明确设置 ApartmentState

    Thread t = new Thread( ... );
    t.SetApartmentState( ApartmentState.STA );
    t.Start();
    

    【讨论】:

    • 你能给我看看示例代码吗?我对这项技术非常陌生。
    • 我怎么知道使用这个任务完成了?
    • 我建议阅读Joe Albahari 了解基础知识。如果你想要一个 STA,你必须使用线程而不是任务,所以你没有ContinueWith。您将不得不在您的线程方法中使用Dispatcher.Invoke
    • @user995387 - 除非您报告线程的进度,否则您无法知道线程何时完成,这完全取决于调度程序。
    【解决方案2】:

    您不能在与主 UI 线程不同的线程上创建 UI 对象,因为一旦将它们添加到 UI,它就会尝试设置 Parent 属性,并且 WPF 中的线程无法修改在主 UI 线程上创建的对象不同的线程。

    相反,我建议在第二个线程上创建网格数据的列表或集合,并使用ItemsControl 之类的东西将其绑定到 UI。这会将所有 UI 对象保留在主 UI 线程上,而后台处理可以在后台线程上完成。

    要从后台线程更新 UI 对象,例如您的状态标签,我建议使用 Dispatcher 就像 lawrencealan's answer 建议的那样。 Dispatcher 是 WPF 的主 UI 线程的内部消息队列

    【讨论】:

    • 可以为此添加任何示例吗?
    【解决方案3】:

    使用 Dispatcher 作为标签和 Invoke 可能会有所帮助:

    label.Dispatcher.Invoke(
          System.Windows.Threading.DispatcherPriority.Normal,
          new Action(
            delegate()
            {
              label.Content = printerStatus();
            }
        ));
    

    【讨论】:

    • 无法创建网格!它在创建网格对象时显示错误。
    • 网格是什么意思,你的意思是DataGridView或者Simple Grid数据结构。
    • WPF 网格。包含 UI 内容..msdn.microsoft.com/en-us/library/system.windows.controls.grid.aspx
    • 当从另一个线程或后台工作人员中修改不是在同一线程中创建的任何类型的 UI 对象时,您需要使用 Dispatcher。我认为您的 Grid 创建可能是另一个问题,除非您尝试修改现有的 UI 对象。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多