public IAsyncResult BeginGetShippingRatesAsync(decimal weight, string originZipCode, string destinationZipCode, AsyncCallback callback, object state)
        {
            // create object that will store results
            AsyncResult<ShippingRate[]> asyncResult = new AsyncResult<ShippingRate[]>(callback, state);
            ShippingRatesRequest request = new ShippingRatesRequest(asyncResult, 3);

            // launch asynchronous requests, which will complete in parallel
            WebRequest fedExRequest = CreateFedExRequest(weight, originZipCode, destinationZipCode);
            fedExRequest.BeginGetResponse(ar => FedExCallback(request, fedExRequest, ar), null);

            WebRequest upsRequest = CreateUpsRequest(weight, originZipCode, destinationZipCode);
            upsRequest.BeginGetResponse(ar => UpsCallback(request, upsRequest, ar), null);

            WebRequest uspsRequest = CreateUspsRequest(weight, originZipCode, destinationZipCode);
            uspsRequest.BeginGetResponse(ar => UspsCallback(request, uspsRequest, ar), null);

            // return IAsyncResult implementation to client
            return asyncResult;
        }
 private static void UpsCallback(ShippingRatesRequest request, WebRequest webRequest, IAsyncResult asyncResult)
 {
     using (WebResponse response = webRequest.EndGetResponse(asyncResult))
         request.AddRates(GetUpsRates(response));
 }