2014-01-12 53 views
1

我已经实施了堆栈溢出问题的解决方案Implement progressbar in this simple WPF applicationWPF和后台工作者和调用线程必须是STA

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

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

我试图把[STAThread]属性的主窗口code-behind还有MainWindowViewModel构造器内。在这两种情况下都没有改变

我错过了什么?

更新 用户点击命令后,在视图模型调用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(); 
+0

你在哪里创建'BackgroundWorker'? – Douglas

+1

消息中的“调用线程”不是您的UI线程。这是WCF回调线程。您需要使用Dispatcher,SynchronizationContext等将该后台线程的调用编组到您的UI线程中。 –

+0

@Douglas我在按钮单击后使用wcf调用来创建BackgroundWorker。 – user1765862

回答

6

Stack Overflow上有很多这个问题的重复。例如,this question。底线 - 无论何时您创建UI组件,您都必须使用单线程单元(STA)线程。后台工作人员不是STA。因此,您无法在后台工作人员中创建UI组件。您无法从后台工作人员更新UI组件。后台工作人员被设计为在后台运行(有很大的惊喜),可能会收集数据并在稍后返回结果。

+0

因此,当后台工作人员需要某些用户交互时,无法获得它? –

+0

按照定义,后台工作人员不需要用户交互。你的设计有一个合理的问题需要解决。 – theMayer

3

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

相关问题