Example #1
0
        private static async Task <JSONNode> APIRequest(string endpoint, params string[] queries)
        {
            string request = "";

            // Form a complete request
            switch (Version)
            {
            case APIVersion.v1_2:
                request += "https://api.gamejolt.com/api/game/v1_2/";
                break;

            default:
                throw new APIError("Unsupported API version.");
            }
            request += $"{endpoint}?game_id={GameID}";
            foreach (string query in queries)
            {
                request += $"&{query}";
            }

            string   result   = (await AsyncWebRequest.GET(AddSignature(request))).downloadHandler.text;
            JSONNode response = JSON.Parse(result)["response"];

            if (response["success"] == "false")
            {
                throw new APIError(response["message"]);
            }

            return(response);
        }
        /// <summary>
        /// Extracts image links to the TwitPic service from status messages.
        /// </summary>
        /// <param name="status">The status.</param>
        /// <param name="callback">The callback.</param>
        /// <returns>True if an image link was found, false otherwise.</returns>
        private static bool ExtractTwitPicImageLink(string status, GetImageLinkCallback callback)
        {
            Match match = Regex.Match(status, @"http://(www\.)?twitpic.com/(\w+)\b", RegexOptions.IgnoreCase);

            if (!match.Success)
            {
                return(false);
            }

            string twitpic   = match.Groups[0].Value;
            string twitpicId = match.Groups[2].Value;

            status = status.Replace(twitpic, string.Empty).Trim();

            AsyncWebRequest request = new AsyncWebRequest();

            request.Request(new Uri(string.Format(CultureInfo.InvariantCulture, "http://api.twitpic.com/2/media/show.xml?id={0}", twitpicId)));
            request.Result += (sender, e) =>
            {
                if (e.Status != HttpStatusCode.OK)
                {
                    callback(null, status);
                }
                else
                {
                    callback(new Uri(@"http://twitpic.com/show/large/" + match.Groups[2].Value), status);
                }
            };

            return(true);
        }
        internal static void GetFlickrUserIdFromUserName(string username, string apiKey, GetFlickrUserIdFromUserNameCallback callback)
        {
            if (_flickrUserNameCache.ContainsValue(username))
            {
                callback((from kvp in _flickrUserNameCache where kvp.Value == username select kvp.Key).FirstOrDefault());
                return;
            }

            string          query   = string.Format(CultureInfo.InvariantCulture, "http://api.flickr.com/services/rest/?method=flickr.people.findByUsername&api_key={0}&username={1}", apiKey, username);
            AsyncWebRequest request = new AsyncWebRequest();

            request.Request(new Uri(query));
            request.Result += (sender, e) =>
            {
                if (e.Status != HttpStatusCode.OK)
                {
                    callback(null);
                }

                try
                {
                    string userid = XDocument.Parse(e.Response).Element("rsp").Element("user").Attribute("nsid").Value;
                    _flickrUserNameCache[userid] = username;
                    callback(userid);
                }
                catch
                {
                    callback(null);
                }
            };
        }
        internal static void GetFlickrGroupIdFromGroupName(string groupname, string apiKey, GetFlickrGroupIdFromGroupNameCallback callback)
        {
            if (_flickrGroupNameCache.ContainsValue(groupname))
            {
                callback((from kvp in _flickrGroupNameCache where kvp.Value == groupname select kvp.Key).FirstOrDefault());
                return;
            }

            string          groupurl = string.Format(CultureInfo.InvariantCulture, "http://www.flickr.com/groups/{0}", groupname);
            string          query    = string.Format(CultureInfo.InvariantCulture, "http://api.flickr.com/services/rest/?method=flickr.urls.lookupGroup&api_key={0}&url={1}", apiKey, groupurl);
            AsyncWebRequest request  = new AsyncWebRequest();

            request.Request(new Uri(query));
            request.Result += (sender, e) =>
            {
                if (e.Status != HttpStatusCode.OK)
                {
                    callback(null);
                }

                try
                {
                    string groupid = XDocument.Parse(e.Response).Element("rsp").Element("group").Attribute("id").Value;
                    _flickrUserNameCache[groupid] = groupname;
                    callback(groupid);
                }
                catch
                {
                    callback(null);
                }
            };
        }
        internal static void GetTwitterUserIdFromUserName(string username, GetTwitterUserIdFromUserNameCallback callback)
        {
            if (_twitterUserNameCache.ContainsValue(username))
            {
                callback((from kvp in _twitterUserNameCache where kvp.Value == username select kvp.Key).FirstOrDefault());
                return;
            }

            string          query   = string.Format(CultureInfo.InvariantCulture, "http://api.twitter.com/1/users/show.xml?screen_name={0}", username);
            AsyncWebRequest request = new AsyncWebRequest();

            request.Request(new Uri(query));
            request.Result += (sender, e) =>
            {
                if (e.Status != HttpStatusCode.OK)
                {
                    callback(null);
                }

                try
                {
                    string userid = XDocument.Parse(e.Response).Element("user").Element("id").Value;
                    _twitterUserNameCache[userid] = username;
                    callback(userid);
                }
                catch
                {
                    callback(null);
                }
            };
        }
Example #6
0
        public static void GetFlickrImageSizes(ImageFeedItem imageFeedItem, string flickrApiKey, GetFlickrImageSizesCallback callback)
        {
            if (imageFeedItem == null || (imageFeedItem.Sizes != null && imageFeedItem.Sizes.Count > 0) || imageFeedItem.SourceType != SourceType.Flickr)
            {
                callback(imageFeedItem);
            }

            string          query   = string.Format(CultureInfo.InvariantCulture, "http://api.flickr.com/services/rest/?method=flickr.photos.getSizes&api_key={0}&photo_id={1}", flickrApiKey, imageFeedItem.ServiceId);
            AsyncWebRequest request = new AsyncWebRequest();

            request.Request(new Uri(query));
            request.Result += (sender, e) =>
            {
                if (e.Status != HttpStatusCode.OK)
                {
                    callback(imageFeedItem);
                }

                try
                {
                    XDocument doc = XDocument.Parse(e.Response);
                    imageFeedItem.Sizes = new Dictionary <Size, Uri>();
                    foreach (XElement size in doc.Descendants("size"))
                    {
                        imageFeedItem.Sizes[new Size(int.Parse(size.Attribute("width").Value, CultureInfo.InvariantCulture), int.Parse(size.Attribute("height").Value, CultureInfo.InvariantCulture))] = new Uri(size.Attribute("source").Value);
                    }

                    callback(imageFeedItem);
                }
                catch
                {
                    callback(imageFeedItem);
                }
            };
        }
Example #7
0
        /// <summary>
        /// Initializes a new instance of the <see cref="FeedSource"/> class.
        /// </summary>
        /// <param name="configuration">The configuration.</param>
        /// <param name="location">The feedlist URL</param>
        internal BanditFeedSource(INewsComponentsConfiguration configuration, SubscriptionLocation location)
        {
            p_configuration = configuration;
            if (p_configuration == null)
            {
                p_configuration = DefaultConfiguration;
            }

            this.location = location;

            // check for programmers error in configuration:
            ValidateAndThrow(Configuration);

            LoadFeedlistSchema();

            rssParser = new RssParser(this);

            if (!String.IsNullOrEmpty(EnclosureFolder))
            {
                enclosureDownloader = new BackgroundDownloadManager(this);
                enclosureDownloader.DownloadCompleted += OnEnclosureDownloadComplete;
            }

            AsyncWebRequest = new AsyncWebRequest();
            AsyncWebRequest.OnAllRequestsComplete += OnAllRequestsComplete;
        }
    protected void Page_Load(object sender, EventArgs e)
    {
        //IMPORTANT: Keep in mind that this async Web Request ALWAYS keeps running after you close the Webpage.
        var req = new AsyncWebRequest();

        req.ExecuteRequest();
    }
Example #9
0
    private void SubmitName(string arg0)
    {
        Text output = receive_output.GetComponent <Text>();

        output.text = "connecting to server...";
        AsyncWebRequest.Post(server_api, arg0, UpdateResponseText, this);
        //Debug.Log(arg0);
    }
        /// <summary>
        /// Creates a new asynchronous web operation pair.
        /// </summary>
        /// <param name="request">The asynchronous web request. It cannot be null.</param>
        /// <param name="result">The resuest result. It cannot be null.</param>
        public AsyncWebOperation(AsyncWebRequest request, IAsyncResult result)
        {
            // Validate the arguments.
            if (null == request) throw new ArgumentNullException("request");
            if (null == result) throw new ArgumentNullException("result");

            this.request = request;
            this.result = result;
        }
Example #11
0
        /// <summary>
        /// Handles the result event from AsyncWebRequest to process the result.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="FeedProcessor.Net.AsyncWebResultEventArgs"/> instance containing the event data.</param>
        private void Request_Result(AsyncWebRequest sender, AsyncWebResultEventArgs e)
        {
            if (e.Status == HttpStatusCode.OK)
            {
                ProcessResponse(e.Response);
            }

            _retryDateTime = RetryTime(e.Status);

            _timer.Start();
        }
Example #12
0
        public static FavIconDescriptor RequestIcon(string baseUri, IWebProxy proxy, ICredentials credentials)
        {
            if (baseUri == null)
            {
                throw new ArgumentNullException("baseUri");
            }

            if (proxy == null)
            {
                proxy = GlobalProxySelection.GetEmptyWebProxy();
            }

            FavIconDescriptor ico = null;

            try {
                using (Stream stream = AsyncWebRequest.GetSyncResponseStream(baseUri, credentials, "RssBandit", proxy)) {
                    string htmlContent = string.Empty;
                    using (StreamReader reader = new StreamReader(stream)) {
                        htmlContent = reader.ReadToEnd();
                        ico         = RequestIcon(baseUri, htmlContent, proxy, credentials);
                    }
                }
            } catch {
                // no default HTML page to examine for a FavIcon entry.
                // we do not stop here: try to get a direct download by requesting favicon.ico directly
            }

            string realIconUrl = null;

            if (ico == null || ico == FavIconDescriptor.Empty)
            {
                try {
                    Uri b = new Uri(new Uri(baseUri), "favicon.ico");
                    realIconUrl = b.ToString();
                } catch (UriFormatException) {}
            }

            if (realIconUrl == null)
            {
                return(FavIconDescriptor.Empty);
            }

            // now get the icon stream
            using (Stream stream = AsyncWebRequest.GetSyncResponseStream(realIconUrl, credentials, "RssBandit", proxy)) {
                Image img = CheckAndScaleImageFromStream(stream);
                if (img != null)
                {
                    return(new FavIconDescriptor(realIconUrl, baseUri, DateTime.Now, img));
                }
            }

            return(FavIconDescriptor.Empty);
        }
Example #13
0
        /// <summary>
        /// Initiates a request to the feed service.
        /// </summary>
        protected virtual void Poll()
        {
            if (_retryDateTime > DateTime.Now)
            {
                return;
            }

            _timer.Stop();

            AsyncWebRequest request = new AsyncWebRequest();

            request.Result += Request_Result;
            request.Request(BuildQuery());
        }
        public async Task Start()
        {
            string path = $"{Application.persistentDataPath}/{ResourceName}";

            if (Directory.Exists(path))
            {
                await AsyncWebRequest.Load(path, HandleLoadLocalResourceMainfest);
            }
            else
            {
                TextAsset resourceAsset = Resources.Load <TextAsset>(Path.GetFileNameWithoutExtension(ResourceName));
                GeneratAssetManifest(resourceAsset.bytes);
            }
        }
        private static bool ExtractYFrogImageLink(string status, GetImageLinkCallback callback)
        {
            Match match = Regex.Match(status, @"http://(www\.)?yfrog.com/(\w+)\b", RegexOptions.IgnoreCase);

            if (!match.Success)
            {
                return(false);
            }

            status = status.Replace(match.Groups[0].Value, string.Empty).Trim();
            AsyncWebRequest request = new AsyncWebRequest();

            request.Request(new Uri("http://yfrog.com/api/xmlInfo?path=" + match.Groups[2].Value));
            request.Result += (sender, e) =>
            {
                if (e.Status != HttpStatusCode.OK)
                {
                    callback(null, status);
                }

                try
                {
                    using (StringReader stringReader = new StringReader(e.Response))
                    {
                        XmlTextReader xmlTextReader = new XmlTextReader(stringReader);
                        while (xmlTextReader.Read())
                        {
                            if (xmlTextReader.MoveToContent() == XmlNodeType.Element && xmlTextReader.Name == "image_link")
                            {
                                string uriString = xmlTextReader.ReadString();
                                string extension = Path.GetExtension(uriString).ToUpper(CultureInfo.InvariantCulture);
                                if (extension == ".JPG" || extension == ".PNG" || extension == ".GIF")
                                {
                                    // sometimes there will be video files, and we don't want that.
                                    callback(new Uri(uriString), status);
                                }
                            }
                        }
                    }
                }
                catch
                {
                    callback(null, status);
                }
            };

            return(true);
        }
Example #16
0
        public static FavIconDescriptor RequestIcon(string baseUri, string htmlContent, IWebProxy proxy, ICredentials credentials)
        {
            if (htmlContent == null || htmlContent.Length == 0)
            {
                return(FavIconDescriptor.Empty);
            }

            if (proxy == null)
            {
                proxy = WebProxy.GetDefaultProxy();
            }

            string realIconUrl = null;

            //<link rel="shortcut icon" href="url to an .ico">
            MatchCollection matches = autoDiscoverRegex.Matches(htmlContent);

            foreach (Match match in matches)
            {
                if (String.Compare(match.Groups["attName"].Value, "rel", true) == 0)
                {
                    string url = match.Groups["href"].Value;
                    realIconUrl = ConvertToAbsoluteUrl(url, baseUri);
                    break;
                }
            }

            if (realIconUrl == null)
            {
                return(FavIconDescriptor.Empty);
            }

            // now get the icon stream
            using (Stream stream = AsyncWebRequest.GetSyncResponseStream(realIconUrl, credentials, "RssBandit", proxy)) {
                Image img = CheckAndScaleImageFromStream(stream);
                if (img != null)
                {
                    return(new FavIconDescriptor(realIconUrl, baseUri, DateTime.Now, img));
                }
            }

            return(FavIconDescriptor.Empty);
        }
        private static bool ExtractTweetPhotoImageLink(string status, GetImageLinkCallback callback)
        {
            Match match = Regex.Match(status, @"http://(www\.)?tweetphoto.com/(\d+)\b", RegexOptions.IgnoreCase);

            if (!match.Success)
            {
                return(false);
            }

            status = status.Replace(match.Groups[0].Value, string.Empty).Trim();
            AsyncWebRequest request = new AsyncWebRequest();

            request.Request(new Uri("http://tweetphotoapi.com/api/tpapi.svc/photos/" + match.Groups[2].Value));
            request.Result += (sender, e) =>
            {
                if (e.Status != HttpStatusCode.OK)
                {
                    callback(null, status);
                }

                try
                {
                    using (StringReader stringReader = new StringReader(e.Response))
                    {
                        XmlTextReader reader = new XmlTextReader(stringReader);
                        while (reader.Read())
                        {
                            if (reader.MoveToContent() == XmlNodeType.Element && reader.Name == "BigImageUrl")
                            {
                                callback(new Uri(reader.ReadString()), status);
                            }
                        }
                    }
                }
                catch
                {
                    callback(null, status);
                }
            };

            return(true);
        }
Example #18
0
 public static async Task<List<Models.SelfiePeekDataModel>> MakeInstagramRequest(int currentIdx = 0)
 {
     try
     {
         var valuesList = await Task.Run(async () =>
         {
             List<Models.SelfiePeekDataModel> returnList = null;
             AsyncWebRequest client = new AsyncWebRequest();
             var apiRequestURL = SharedStrings.InstagramAPIBaseURI + SharedStrings.CurrentToken;
             var resp = await client.MakeRequest<Models.InstagramRawBase>(apiRequestURL);
             int colSpan = currentIdx;
             if (resp != null && resp.data != null && resp.data.Count > 0)
             {
                 var data = resp.data;
                 returnList = new List<Models.SelfiePeekDataModel>();
                 foreach (var item in data)
                 {
                     var extracted = new Models.SelfiePeekDataModel();
                     extracted.UserName = item.user.username;
                     extracted.Thumbnail = new Uri(item.images.standard_resolution.url);
                     extracted.Caption = item.caption.text;
                     var tags = new List<string>();
                     foreach (var tag in item.tags)
                     {
                         tags.Add(tag);
                     }
                     extracted.Tags = tags;
                     extracted.ColSpan = (colSpan++ % 3 == 0) ? 2 : 1;
                     returnList.Add(extracted);
                 }
             }
             return returnList;
         });
         return valuesList;
     }
     catch (Exception)
     {
         return null;
     }
 }
Example #19
0
        /// <summary>
        /// Retrieves the RSS feed for a particular subscription then converts
        /// the blog posts or articles to an arraylist of items. The http requests are async calls.
        /// </summary>
        /// <param name="feedUrl">The URL of the feed to download</param>
        /// <param name="forceDownload">Flag indicates whether cached feed items
        /// can be returned or whether the application must fetch resources from
        /// the web</param>
        /// <param name="manual">Flag indicates whether the call was initiated by user (true), or
        /// by automatic refresh timer (false)</param>
        /// <exception cref="ApplicationException">If the RSS feed is not version 0.91, 1.0 or 2.0</exception>
        /// <exception cref="XmlException">If an error occured parsing the RSS feed</exception>
        /// <exception cref="ArgumentNullException">If feedUrl is a null reference</exception>
        /// <exception cref="UriFormatException">If an error occurs while attempting to format the URL as an Uri</exception>
        /// <returns>true, if the request really was queued up</returns>
        /// <remarks>Result arraylist is returned by OnUpdatedFeed event within UpdatedFeedEventArgs</remarks>
        //	[MethodImpl(MethodImplOptions.Synchronized)]
        public override bool AsyncGetItemsForFeed(string feedUrl, bool forceDownload, bool manual)
        {
            if (feedUrl == null || feedUrl.Trim().Length == 0)
            {
                throw new ArgumentNullException("feedUrl");
            }

            string etag          = null;
            bool   requestQueued = false;

            int priority = 10;

            if (forceDownload)
            {
                priority += 100;
            }
            if (manual)
            {
                priority += 1000;
            }

            Uri feedUri = new Uri(feedUrl);

            NewsFeed theFeed = null;

            //see if we've retrieved the news feed before
            if (feedsTable.ContainsKey(feedUri.CanonicalizedUri()))
            {
                theFeed = feedsTable[feedUri.CanonicalizedUri()] as NewsFeed;
            }

            if (theFeed == null) //feed list is corrupted
            {
                return(false);
            }

            // raise event only if we "really" go over the wire for an update:
            RaiseOnUpdateFeedStarted(feedUri, forceDownload, priority);

            //DateTime lastRetrieved = DateTime.MinValue;
            DateTime lastModified = DateTime.MinValue;

            if (itemsTable.ContainsKey(feedUrl))
            {
                etag         = theFeed.etag;
                lastModified = (theFeed.lastretrievedSpecified ? theFeed.lastretrieved : theFeed.lastmodified);
            }

            Dictionary <string, string> parameters = new Dictionary <string, string>();

            parameters.Add("viewer_id", this.facebookUserId);
            parameters.Add("session_key", this.sessionKey);
            parameters.Add("method", "stream.get");

            /* FQL
             * string query = String.Format("?query=select post_id, source_id, created_time, actor_id, target_id, app_id, message, attachment, comments, likes, permalink, attribution, type from stream where filter_key in (select filter_key FROM stream_filter where uid = {0} and type = 'newsfeed') and created_time >= {1} order by created_time desc limit 50", facebookUserId, updatedTime);
             * parameters = "&v=1.0&method=fql.query&format=JSON&call_id={0}&session_key={1}&api_key={2}&sig={3}";
             */

            string reqUrl = feedUrl + "?" + CreateHTTPParameterList(parameters, false /* useJson */);

            Uri reqUri = new Uri(reqUrl);

            try
            {
                try
                {
                    if ((!forceDownload) || Offline)
                    {
                        GetCachedItemsForFeed(feedUri.CanonicalizedUri()); //load feed into itemsTable
                        RaiseOnUpdatedFeed(feedUri, null, RequestResult.NotModified, priority, false);
                        return(false);
                    }
                }
                catch (XmlException xe)
                {
                    //cache file is corrupt
                    Trace("Unexpected error retrieving cached feed '{0}': {1}", feedUrl, xe.ToDescriptiveString());
                }

                ICredentials c = null;

                RequestParameter reqParam =
                    RequestParameter.Create(reqUri, this.UserAgent, this.Proxy, c, lastModified, etag);
                reqParam = RequestParameter.Create(false, reqParam);

                AsyncWebRequest.QueueRequest(reqParam,
                                             OnRequestStart,
                                             OnRequestComplete,
                                             OnRequestException, priority);

                requestQueued = true;
            }
            catch (Exception e)
            {
                Trace("Unexpected error on QueueRequest(), processing feed '{0}': {1}", feedUrl, e.ToDescriptiveString());
                RaiseOnUpdateFeedException(feedUrl, e, priority);
            }

            return(requestQueued);
        }
 /// <summary>
 /// Static constructor
 /// </summary>
 static BackgroundDownloadManager()
 {
     asyncWebRequest = new AsyncWebRequest();
 }
 public async Task Init()
 {
     string path = $"{GameConfig.Instance.RemoteSettingUrl}/{PlatformHelper.GetPlatformString()}/GameConfig.json";
     await AsyncWebRequest.Load(path, InitRemoteConfig);
 }
        // Public methods.
        /// <summary>
        /// Adds the result of an asynchronous web operation to the collection of web requests.
        /// </summary>
        /// <param name="request"></param>
        /// <param name="result">The result of the web request.</param>
        public AsyncWebOperation AddAsyncWeb(AsyncWebRequest request, AsyncWebResult result)
        {
            // Create the asynchronous web operation.
            AsyncWebOperation operation = new AsyncWebOperation(request, result);

            lock (this.sync)
            {
                // Add the result.
                this.asyncWeb.Add(operation);
            }

            // Return the web operation.
            return operation;
        }
 protected void Page_Load(object sender, EventArgs e)
 {
     //IMPORTANT: Keep in mind that this async Web Request ALWAYS keeps running after you close the Webpage.
     var req = new AsyncWebRequest();
     req.ExecuteRequest();
 }
Example #24
0
 // Use this for initialization
 void Start()
 {
     //AsyncWebRequest.Get("http://*****:*****@"{""test"":""test1""}", printWebResponse, this);
     //print (@"{""test"":""test1""}");
 }
Example #25
0
        /// <summary>
        /// Sends a request
        /// </summary>
        /// <param name="uri">The full URI of the request</param>
        /// <param name="method">The request method (GET/POST)</param>
        /// <param name="form">A WWWForm to include with the request</param>
        /// <param name="onFinished">Called when the request is finished</param>
        /// <param name="silent">Whether or not to log errors while making the request</param>
        /// <returns></returns>
        public IEnumerator makeRequestAsync(string uri, string method, WWWForm form = null, Action <string> onFinished = null, bool silent = false)
        {
            ErrorMessage    = null;
            IsDoneUploading = false;
            UploadError     = false;
            UploadException = null;

            AsyncWebRequest request = new AsyncWebRequest();

            if (method == "GET")
            {
                yield return(request.Get(uri));
            }
            else if (method == "POST")
            {
                yield return(request.Post(uri, form));
            }
            else
            {
                UploadError  = true;
                ErrorMessage = "Unsupported request method: " + method;

                if (!silent)
                {
                    Debug.LogError("Error making request to Trello API!");
                    Debug.LogError(ErrorMessage);
                }

                yield break;
            }

            IsDoneUploading = true;

            string response = null;

            if (request.UploadException != null)
            {
                UploadException = request.UploadException;
                UploadError     = true;
                ErrorMessage    = "Error making request to Trello API!";

                // log error
                if (!silent)
                {
                    Debug.LogError("Error Making Request to Trello API!");
                    Debug.LogException(request.UploadException);
                }
            }
            else if (request.Request.responseCode != (long)HttpStatusCode.OK && !silent)
            {
                UploadError  = true;
                ErrorMessage = "Trello API: Error " + request.Request.responseCode;

                // log error
                if (!silent)
                {
                    Debug.LogError("Error Making Request to Trello API!");
                    Debug.LogError("Status Code " + request.Request.responseCode + ": " + request.Request.downloadHandler.text);
                }
            }
            else if (request.RequestIsError && !silent)
            {
                UploadError  = true;
                ErrorMessage = "Error making request to Trello API!";

                // log error
                if (!silent)
                {
                    Debug.LogError("Error Making Request to Trello API!");
                    Debug.LogError(request.Request.error);
                }
            }
            else
            {
                // get response text
                response = request.Request.downloadHandler.text;
            }

            // handle callback
            if (onFinished != null)
            {
                onFinished(response);
            }
        }
        /// <summary>
        /// Adds an asynchronous web operation.
        /// </summary>
        /// <param name="request">The asynchronous request.</param>
        /// <param name="result">The asynchronous result.</param>
        /// <returns>The asynchronous operation.</returns>
        internal AsyncWebOperation BeginAsyncOperation(AsyncWebRequest request, IAsyncResult result)
        {
            // Create the asynchronous web operation.
            AsyncWebOperation operation = new AsyncWebOperation(request, result);

            lock (this.sync)
            {
                // Verify that the operation does not exist.
                if (this.asyncOperations.Contains(operation)) throw new InvalidOperationException("Cannot begin an asynchronous operation because the same operation already exists.");

                // Add the operation to the list.
                this.asyncOperations.Add(operation);

                // Set the wait handle to the non-signaled state.
                this.waitAsync.Reset();
            }

            return operation;
        }