2013-12-19 40 views
0

我有一个后台工作人员,可以完成一些工作。我想要一个主控制器上的微调表明该应用程序正在工作。但看起来像线程正在阻止我的微调动画(有时它甚至不显示)......有人可以解释为什么它不工作(可能是因为睡觉的线程),也许可以指导我以最小代码更改的解决方案:)当后台线程正在工作时进度条(微调)不动画

此致敬礼,no9。

public void StartProcess(object obj) 
{ 

    this.eventAggregator.GetEvent<ActionEvent>().Publish(new Message(EMessageType.Info) 
    { 
    Title = "Start", 
    Description = "Starting action..." 
    }); 

    Worker = new BackgroundWorker(); 
    Worker.DoWork += new DoWorkEventHandler(worker_DoWork); 
    Worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted); 

    try 
    { 
    this.Document = null; 
    Dictionary<string, Stream> tmp = this.GetContent(); 
    //start and show the spinner 
    this.View.ShowDocumentProgressSpinner(true); 
    Worker.RunWorkerAsync(tmp); 
    } 

    catch (Exception ex) 
    { 
    ExceptionPolicy.HandleException(ex, "LogAndSwallow"); 
    this.eventAggregator.GetEvent<ActionEvent>().Publish(new Message(EMessageType.Error) 
    { 
     Title = "Error", 
     Description = "There was an error processing your action." 
    }); 
    } 
    finally 
    { 
    this.View.ShowActionButton(false); 
    } 
} 


private void worker_DoWork(object sender, DoWorkEventArgs e) 
{ 
    var logger = new ActionLoggerAndViewUpdater(this.eventAggregator, this.View); 
    foreach (KeyValuePair<string, Stream> pair in (Dictionary<string, Stream>)e.Argument) 
    { 
    using (Stream stream = pair.Value) 
    { 
     //setting the document fires login event that changes stuff on presenter (current class instance) 
     this.Document = new Document(stream); 

     //check if ok to continue 
     while (!this.IsLoggedInForTheWorkingDocument) 
     //wait of the login stuff to complete 
     Thread.Sleep(2000); 

     System.Windows.Application.Current.Dispatcher.Invoke((Action)(() => 
     { 
     //this depends on the login and takes some time to process 
     this.DoSomeStuff(); 
     })); 
    } 
    } 
} 

private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    //stop and hide the spinner 
    this.View.ShowDocumentProgressSpinner(false); 
    ... 
} 
+0

if this.View.ShowDocumentProgressSpinner(true);正在更新你的UI,那么你应该在worker_DoWork方法中使用这个,因为这是在不同的线程。 –

+0

它的一个控制...它不允许从另一个线程更新主线程线程... – no9

回答

2

更新为什么你调用你的后台工作的东西吗?后台工作者的全部目的是在而不是在UI线程中运行并阻止它。不要从工人调用一个长时间运行的进程,这会影响它的目的。

private void worker_DoWork(object sender, DoWorkEventArgs e) 
{ 
    var logger = new ActionLoggerAndViewUpdater(this.eventAggregator, this.View); 
    foreach (KeyValuePair<string, Stream> pair in (Dictionary<string, Stream>)e.Argument) 
    { 
    using (Stream stream = pair.Value) 
    { 
     this.Document = new Document(stream); 

     // this should REALLY be handled by an event, not busy waiting: 
     while (!this.IsLoggedInForTheWorkingDocument) 
     //wait of the login stuff to complete 
      Thread.Sleep(2000); 

     // removed the invoking, this is supposed to run in the background, right? 
     this.DoSomeStuff(); 
    } 
    } 
} 
+0

上的答案链接的东西更新UI,我需要使用UI线程......它的设计我不能围绕......调用“DoSomeStuff”而不调用抛出“另一个线程”异常。 – no9

+0

如果*必须*更新UI,那么你应该跳过你的后台工作。它不再是后台工作。也许你可以找到一个更好的策略,例如先在后台生成结果,然后在后台完成繁重的工作时更新UI。 – nvoigt

+0

我不得不使用它。我会尽力展开。当设置“this.Document”事件在后台执行登录,更新用户界面和更改课堂上的某些内容时,我将全部掌握。只有登录完成后才可以打电话给“DoSomeStuff”。我只能用bckgWorker来实现这一点。看到我原来的帖子:http://stackoverflow.com/questions/20515598/wait-for-an-event-to-finish-threading。设置“this.Document”时触发此事件 – no9

0

因为您的工作人员在另一个线程中运行,所以无法更新UI线程,因为它的行为。看到另一个类似的问题Updating GUI (WPF) using a different thread

基本上你需要调用control.Dispatcher.Invoke让你的UI从其他线程

+0

我已经尝试把工作进度微调内部和通过主应用程序调度程序更新它...相同的结果 – no9

+0

微调器可以坐在UI层,它应该在那里。这个问题在这里http://msdn.microsoft.com/en-us/magazine/cc163328.aspx详细讨论,通过前面的SO问题 – Dave