Silverlight, dealing with Async calls

后端 未结 8 1226
走了就别回头了
走了就别回头了 2021-01-03 01:23

I have some code as below:

        foreach (var position in mAllPositions)
        {
                 DoAsyncCall(position);
        }
//I want to execute co         


        
相关标签:
8条回答
  • 2021-01-03 02:10

    (NB, I am giving two separate answers; this takes a totally different approach than in the question.)

    Following the code sample by Miguel Madero at this URL, use the Reactive Framework to wait in parallel for all the results to complete, then follow on with another task.

    (There's other discussion in the same email chain, including a link to this closely related StackOverflow question.)

    0 讨论(0)
  • 2021-01-03 02:11

    I don't see this as a "I want to do a synchronous call" problem. All you're really doing is tying a series of async calls together when they are all complete.

    I have encountered this before in the case where you have a list of items and need to asynchronously get attributes for them from the server (some for of status for instance) but also want to update some loading progress indicator on the screen.

    In this situation you don't want to block the UI thread while all of the items are being updated (blocking threads is evil anyway if there is an alternative).

    So I used a control class like this:

    public class GroupAction
    {
        public delegate void ActionCompletion();
    
        private uint _count = 0;
        private ActionCompletion _callback;
        private object _lockObject = new object();
    
        public GroupAction(uint count, ActionCompletion callback)
        {
            _count = count;
            _callback = callback;
        }
    
        public void SingleActionComplete()
        {
            lock(_lockObject)
            {
                if (_count > 0)
                {
                    _count--;
                    if (_count == 0) _callback();
                }
            }
        }
    }
    

    You create this action with a count (for the number of items) and a callback that gets executed on completion of all the items. Basically like a semaphore with more control and no threading to worry about.

    The calling code would look something like this (I have based the example on calling the standard temp conversion web service you can find at w3schools.com).

        private void DoGroupCall()
        {
            uint count = 5;
            GroupAction action = new GroupAction(count,
                () =>
                {
                    MessageBox.Show("Finished All Tasks");
                });
    
            for (uint i = 0; i < count; i++)
            {
                TempConvertHttpPost proxy = new TempConvertHttpPostClient(new BasicHttpBinding(), new EndpointAddress("http://localhost/webservices/tempconvert.asmx"));
                CelsiusToFahrenheitRequest request = new CelsiusToFahrenheitRequest() { Celsius = "100" };
    
                proxy.BeginCelsiusToFahrenheit(request,
                      (ar) => Deployment.Current.Dispatcher.BeginInvoke(
                          () =>
                          {
                              CelsiusToFahrenheitResponse response = proxy.EndCelsiusToFahrenheit(ar);
    
                              // Other code presumably...
    
                              action.SingleActionComplete();
                          }
                      ), null);
            }
        }
    

    Note how the GroupAction instance is defined with an inline callback delegate and then the SingleCallBack function is called each time the service returns.

    Hope this helps...

    0 讨论(0)
提交回复
热议问题