views:

58

answers:

2

I have a silverlight 4 web app that needs to communicate with a server by accessing the ASMX web service on the server. I have a list(yes, the array), of objects that I need to send(one by one) as a parameter to the service. However looping through the list and running the method(objecttosend); will not work because I need to send then one after another and Silverlight seems to only support Async(presumably to not lockup interface - makes sense).

So I tried this:

public void SendNextPart()
    {
        if (partsToSend.Count > 0)
        {
            Part thisPart = partsToSend.Dequeue();
            fuWS.createPartCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(fuWS_createPartCompleted);
            fuWS.createPartAsync(thisPart);

        }
    }
Queue<Part> partsToSend = new Queue<Part>();
    void fuWS_createPartCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            SendNextPart();
        }

Which, as far as I can understand it, will check to see if the List has parts to send, then run the webservice(called fuWS) method and delete that part from the partsToSend List. Once it gets the completed event it should then run the SendNextPart method again and send the next part.

However what is happening(picked this up by watching HTTPwatch) is that it sends the first part, then after that is sends 2 parts at once and then after that more and more, all at once. Almost as if it is receiving the completed event before it has actually sent to the server and run the method successfully.

Please help, this is bugging the hell out of me, and it completely breaks what I need to do :'(

+1  A: 

I don't see the SendNextBuffer method that you're calling in the web service callback event handler. But in any case, at best your code has a race condition. If the web service completes and returns before the partsToSend.RemoveAt line is executed (theoretically possible) then you could be making the next request before you've removed the one you just sent.

So first, you should check to make sure you've included all the code in your example unless you meant for SendNextBuffer to say SendNextPart.

Secondly, you should move the partsToSend.RemoveAt line before the web service call.

Finally, you should probably change the partsToSend list into a Queue<Part> (first in, first out) or Stack<Part> (last in, first out) instead since that is what you're using it as.

Josh Einstein
Sorry, in editing it to put here I managed to change SendNextPart and SendNextBuffer to different things :PThey are the same. I have edited my original post, along with changing the code to using a queue(FIFO or LILO are both fine) - but it still works exactly the same
Matt
A: 

Ok, so after using Debug.WriteLine, I realized that I was being an idiot. Check out this line:

fuWS.createPartCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(fuWS_createPartCompleted);

What this was doing was adding a new event handler every time it had to send a new part. So the second part sending now had two callback then the third would have more and so on increasing exponentially.

Matt