2014-05-08 28 views
0

所以最后我设法创建了一个工作的BackgroundWorker。WPF mvvm backgroundworker UI显示不同的结果

我使用ReportProgress方法来更新UI元素以这样的方式

bw.ReportProgress(1, node); 
bw.ReportProgress(2, connection); 
bw.ReportProgress(3); 
bw.ReportProgress(4, system); 

当连接是模型对象,这是我的进步方法:

void bw_ProgressChanged(object sender, ProgressChangedEventArgs e) 
    { 
     if (e.ProgressPercentage == 1)  //update nodes 
     { 
      this.Network.Nodes.Add((NodeViewModel)e.UserState); 
     } 
     if (e.ProgressPercentage == 2)  //update connections 
     { 
      this.Network.Connections.Add((ConnectionViewModel)e.UserState); 
     } 
     if (e.ProgressPercentage == 3) 
     { 
      this.Network.Connections.Clear(); 
      this.Network.Nodes.Clear(); 
     } 
     if (e.ProgressPercentage == 4) 
     { 
      MainNet.Systems.Add((Common.Model.System)e.UserState); 
     } 
    } 

我有多个对象更新,所以我用百分比作为过滤器。

我得到不同的结果每次我运行代码的时候,就好像一些数据是不正确的UI

UI的正确形式呈现:

This is the correct form of UI

不纠正:

This is not correct

+0

你能否提供更多关于如何调用ReportProgress()的细节? – Slugart

+0

这是一个竞赛条件吗? –

+0

@GarryVass什么是比赛条件? Slugart - 它在上面的主要信息,这是所有'ReportProgress'调用,我也有其他电话,现在不适合添加它们 – Yogevnn

回答

1

如果你需要你的工人(S)同步,以避免或重入一场比赛,有几种不同的方式。你可以尝试这样的做法...

private static void ManageBackgroundWorkers() 
    { 
     BackgroundWorker backgroundWorker1 = new BackgroundWorker(); 
     BackgroundWorker backgroundWorker2 = new BackgroundWorker(); 
     BackgroundWorker backgroundWorker3 = new BackgroundWorker(); 
     backgroundWorker1.DoWork += (s, a) => 
     { 
      /* do stuff*/ 
     }; 
     backgroundWorker2.DoWork += (s, a) => 
     { 
      /* do some more stuff*/ 
     }; 
     backgroundWorker3.DoWork += (s, a) => 
     { 
      /* do even more different stuff*/ 
     }; 
     backgroundWorker1.RunWorkerCompleted += (s, a) => 
     { 
      //this.Network.Nodes.Add((NodeViewModel)e.UserState); 
      backgroundWorker2.RunWorkerAsync(); 
     }; 
     backgroundWorker2.RunWorkerCompleted += (s, a) => 
     { 
      //this.Network.Connections.Add((ConnectionViewModel)e.UserState); 
      backgroundWorker3.RunWorkerAsync() 
     }; 
     backgroundWorker3.RunWorkerCompleted += (s, a) => 
     { 
      // finish remaining tasks here 
     }; 
     /* start the queue */ 
     backgroundWorker1.RunWorkerAsync(); 
    } 

每个工人信号完成其事件处理程序简单地开始下一个工作人员在系列。这不是你所拥有的巨大差异,而是重新包装你使用“百分比”属性的步骤。无论如何,百分比实际上是一个糟糕的州代理。重构你的代码应该需要大约5分钟。

另一种方法是使用ManualResetEvent对回调进行检测,每次调用时都会发出一个信号。每次调用ReportProgress处理程序后,ManualResetEven都会在worker中等待。梅西耶,较少模块化,但确实可行。

+0

不幸的是,这并不能帮助我的情况,我不能修改主要方法,所以它会被破坏到很多部分,有没有其他方法? – Yogevnn

+0

如果你的学士学位要求你在“主要方法”中做所有事情(不包括在你的问题陈述中),那么考虑换个不同的大学。 –

+0

不不哈哈,不用担心(我的程序中有124个课程和窗口..)但我所说的功能不能被破坏 – Yogevnn