如何在silverlight中处理异步数据接收?
我有一个复选框列表,每次用户选择一项时,我的 ViewModel 都会要求我的服务发送与该选项相关的数据。
_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)
任何人都可以帮我解决这个问题吗?
I have a checkbox list that each time the user selects one item, my ViewModel will ask my service to send the data related to that option.
_myService.GetAssetSpotDataCompleted += GetAssetSpotDataCompleted;
_myService.GetAssetSpotDataAsync(descItem);
Each selected item will call the same service Method and Debugging the service it sends back the right data.
My problem appears when the user checks some of the items while the data is not still received in my ViewModel. Example: the user selects item 1 and item 2, but my viewModel still has no answer from the service.
When my ViewModel receives the information comes the problem, I always receive twice the same data in my e.Result.
That means that it enters to the method GetAssetSpotDataAsync
twice but always with the same result instead of the result for the item 1 and then for the item 2.
I have debugged everything and I have focused the problem in these first two lines of the method GetAssetSpotDataCompleted
:
((MyServiceClient)sender).GetAssetSpotDataCompleted -= GetAssetSpotDataCompleted;
if (e.Result != null)
Anyone can help me with this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
发生的情况是,当对第一个请求的响应到达时,服务发现 2 个委托正在监听
GetAssetSpotDataCompleted
(一个是在发出请求时添加的,另一个是在发出第二个尚未完成的请求时添加的) 。它会呼叫这两个代表,它无法知道第二个代表仅用于第二个未完成的请求。当第一个被调用时,它的代码将从事件中删除一个委托。当调用第二个时,它还会删除剩余的委托,将
GetAssetSpotDataCompleted
保留为 null。现在,当第二个请求最终完成时,服务发现
GetAssetSpotDataCompleted
事件为 null 并且不执行任何操作。一种解决方案是仅添加事件处理程序一次,也许是在 ViewModel 中分配
_myService
的同一点上。然而,可能还有另一个问题,不能保证对两个未完成请求的响应将按照发送的顺序到达(尽管它们很可能会这样做。)最好添加一个
IsBusy
布尔属性添加到 ViewModel 中,并在发出未完成的请求时设置此true
,并在完成时清除它。将此属性绑定到BusyIndicator
控件(可在工具包中找到)。这将阻止用户交互,而最终改变 UI 状态的异步操作正在进行中。What is happening is that by the time the response to first request has arrived the service finds 2 delegates listening on
GetAssetSpotDataCompleted
(one was added when the request was made the other when the second still outstanding request was made).It will call both the delegates, it has no way to know that the second delegate was only meant for the second outstanding request. When the first is called its code removes one of the delegates from the event. When the second is called then it also removes the remaining delegate leaving the
GetAssetSpotDataCompleted
as null.Now when the second request finally completes the service finds
GetAssetSpotDataCompleted
event is null and does nothing.One solution would be to only add the event handler once, perhaps at the same point that
_myService
gets assigned in the ViewModel.However there may be another issue, there is no guarantee that the responses to the two outstanding requests will arrive in the same order they were sent (although it highly likely that they will.) It may be better then to add an
IsBusy
boolean property to the ViewModel and set thistrue
when an outstanding request is made, clearing it when completed. Bind this property to aBusyIndicator
control (found in the Toolkit). This will prevent user interaction whilst an async operation that will ultimate change the state of the UI is in progress.