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?
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
GetAssetSpotDataCompletedas null.Now when the second request finally completes the service finds
GetAssetSpotDataCompletedevent is null and does nothing.One solution would be to only add the event handler once, perhaps at the same point that
_myServicegets 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
IsBusyboolean property to the ViewModel and set thistruewhen an outstanding request is made, clearing it when completed. Bind this property to aBusyIndicatorcontrol (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.