2012-02-14 53 views
1

我有一个复选框列表,每当用户选择一个项目时,我的ViewModel将要求我的服务发送与该选项相关的数据。如何在Silverlight中处理异步数据接收?

_myService.GetAssetSpotDataCompleted += GetAssetSpotDataCompleted; 

_myService.GetAssetSpotDataAsync(descItem); 

每个选定的项目将调用相同的服务方法和调试服务它发回正确的数据。

我的问题出现时,用户检查一些项目,而我的ViewModel中仍然没有收到数据。例如:用户选择项目1和项目2,但我的viewModel仍然没有来自服务的回答。

当我的ViewModel收到信息出现问题时,我总是会在e.Result中收到两次相同的数据。

这意味着,它进入到方法GetAssetSpotDataAsync两次,但始终具有相同的结果,而不是结果,该项目1,然后2

我已经调试的一切项目,我都集中在这个问题这些前两行的方法GetAssetSpotDataCompleted的:

((MyServiceClient)sender).GetAssetSpotDataCompleted -= GetAssetSpotDataCompleted; 
      if (e.Result != null) 

任何人都可以帮助我?

+0

每次用户选择某个项目时,是否需要添加/删除事件处理程序?只有一个声明就足够了 – mslliviu 2012-02-14 12:46:13

回答

0

发生的事情是,到第一个请求的响应到达时,服务发现2个代理正在侦听GetAssetSpotDataCompleted(当第二个未完成请求发出时,另一个是在另一个请求发出时添加的)。

它会调用这两个委托,它无法知道第二个委托仅用于第二个未决请求。当第一个被调用的代码从该事件中删除一个代表时。当第二个被调用时,它也会删除剩下的代表,使GetAssetSpotDataCompleted为空。

现在当第二个请求最终完成时,服务发现GetAssetSpotDataCompleted事件为空并且什么也不做。

一个解决方案是只添加一次事件处理程序,也许在_myService被分配到ViewModel的同一点。

但是,可能存在另一个问题,不能保证对两个未完成请求的响应将按照它们发送的相同顺序到达(尽管它们很可能会发送)。最好是添加一个IsBusy boolean属性给ViewModel,并在发出未完成的请求时设置此true,完成时清除它。将此属性绑定到一个BusyIndicator控件(可在Toolkit中找到)。这将阻止用户交互,而最终会改变UI状态的异步操作正在进行中。