实时应用的MVVM设计

3
问题很简单: 我的View应该显示来自WCF服务的数据。该数据以高频异步更新,因此当服务器端数据发生更改时,GUI应相应地进行更新。
View显示了大量数据,基本上绑定了ViewModel中公开的50/60个字段。
Model部分基本上是一个POCO对象,其中包含在GUI中显示的50/60个字段。是的,ViewModel向View公开了Model对象。(请注意,Model对象实现了INotifyPropertyChanged接口,以便在属性值更改时通知View。)
现在,我编写了一个"DataService"层,它与WCF服务交互,并负责根据WCF服务返回的数据更新Model。当服务器端数据更新时,为了提高性能,WCF服务仅向客户端返回已更改的字段集。
因此,在DataService中有一个事件处理程序,像以下方式管理wcf服务更新:
void OnServiceUpdated(UpdateArgs args)
{
  foreach(Field field in args.ChangedFields)
  {
      if(field.Key == "BetName") _modelBet.BetName = field.Value;
      else if(field.Key == "BetUser") _modelBet.BetUser = field.Value;
      [...]
      //the same for 50 fields...
  }
}

现在这段可怕的代码用于更新模型,因为我们只想更新服务器端未更改的模型字段。(请注意,wcf服务API无法更改。)

我的问题是:您有什么建议来提高"OnServiceUpdated"处理程序的性能?

谢谢! Jhon

1个回答

2
你说:“数据以高频率异步更新。”
根据我的理解,你不想经常对用户界面产生影响。因此,你可以使用调度计时器(dispatcher timer)进行延迟通知。它在 UI 线程上运行,与其他计时器不同。
这里有一个关于调度计时器的 SO 用户http://msdn.microsoft.com/tr-tr/library/system.windows.threading.dispatchertimer.aspx 的答案https://stackoverflow.com/a/15044392/413032
如果你使用 MVVM,那么我会把 args.ChangedFields 和 ViewModel 属性名称设置为相同。这样,我就可以通过反射或使用自动映射器将属性值传输到 ViewModel 属性中。
你还可以在所有属性设置完成后触发事件并更新用户界面。
提供此功能的方法如下:
根据我的理解,你使用了绑定,绑定具有模式和UpdateSourceTrigger选项,所以你可以显式更新源。

http://msdn.microsoft.com/en-us/library/cc278072(v=vs.95).aspx#updating_the_data_source http://msdn.microsoft.com/en-us/library/system.windows.data.updatesourcetrigger.aspx

希望向您展示一条路。

嗨Davut,非常感谢您的回答。 好的,感谢您建议使用Dispatcher TImer,但在这种情况下,UI上频繁更新不是问题。 - user1070316
嗨Davut,非常感谢你的回答。好的,感谢您建议使用Dispatcher Timer,但在这种情况下,UI的频繁更新不是问题。顺便说一下,我会把这个问题单独处理。是的,我已经考虑了您提出的解决方案,因此使用反射将属性值转移到viewModel属性,但出于性能原因,我想避免使用反射。关于Auto-Mapper的建议非常有趣。我将尝试在那个方向上进行调查。谢谢, 约翰 - user1070316
有些人说这个方法https://dev59.com/dmsz5IYBdhLWcg3wHUMU#8111631比反射更快。此外,我不认为反射会引起问题。绑定使用反射,在一个控件下绑定1000个Textblock对象只需要不到1秒钟的时间http://msdn.microsoft.com/en-us/library/bb613546.aspx(渲染时间为1.2秒)。当然,你可以自由地使用自动映射器http://www.codeproject.com/Articles/61629/AutoMapper。这真的取决于你的问题。 - Davut Gürbüz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接