static IEnumerator <int> ListenerFiber(AsyncEnumerator ae) { var listeningServer = new TcpListener(IPAddress.Loopback, 9998); listeningServer.Start(); while (!ae.IsCanceled()) { listeningServer.BeginAcceptTcpClient(ae.End(0, listeningServer.EndAcceptTcpClient), null); yield return(1); if (ae.IsCanceled()) { yield break; } var clientSocket = listeningServer.EndAcceptTcpClient(ae.DequeueAsyncResult()); var clientAe = new AsyncEnumerator() { SyncContext = null }; clientAe.BeginExecute( ClientFiber(clientAe, clientSocket), ar => { try { clientAe.EndExecute(ar); } catch { } }, null); } }
private IEnumerator <int> ProcessUpdateLookups(AsyncEnumerator asyncEnumerator, QuotePage[] pages) { QuotePage page; for (int i = 0; i < pages.Length; i++) { page = pages[i]; LookupResolver.BeginNormalizeTopicOmitChecks(page.Topic, page.Culture, asyncEnumerator.End(AsyncEnumeratorDiscardGroup, LookupResolver.EndNormalizeTopic), page); } IAsyncResult result; bool updateQuotes = false; for (int i = 0; i < pages.Length; i++) { yield return(1); if (asyncEnumerator.IsCanceled()) { yield break; } result = asyncEnumerator.DequeueAsyncResult(); page = result.AsyncState as QuotePage; try { page.Topic = LookupResolver.EndNormalizeTopic(result); page.Uri = LookupResolver.GetUri(page.Topic, page.Culture); } catch { OnTopicNotFound(new TopicNotFoundEventArgs(page.Topic, page.Culture)); yield break; } lock (_lookupsInProgress) { if (!_lookupsInProgress.Contains(page.Uri)) { _lookupsInProgress.Add(page.Uri); updateQuotes = true; } } if (updateQuotes) { QuoteCollector.UpdateQuotesAsync(page); } } lock (_asyncEnumerators) { _asyncEnumerators.Remove(asyncEnumerator); } }
private IEnumerator <int> ProcessLookup(AsyncEnumerator asyncEnumerator, string topic, CultureInfo culture) { LookupResolver.BeginNormalizeTopicOmitChecks(topic, culture, asyncEnumerator.End(AsyncEnumeratorDiscardGroup, LookupResolver.EndNormalizeTopic), null); yield return(1); if (asyncEnumerator.IsCanceled()) { yield break; } try { topic = LookupResolver.EndNormalizeTopic(asyncEnumerator.DequeueAsyncResult()); } catch { OnTopicNotFound(new TopicNotFoundEventArgs(topic, culture)); yield break; } Uri uri = LookupResolver.GetUri(topic, culture); bool collectQuotes = false; lock (_playlist) { if (_playlist.Contains(uri)) { OnTopicAlreadyExists(new TopicAlreadyExistsEventArgs(topic, culture)); yield break; } } lock (_lookupsInProgress) { if (!_lookupsInProgress.Contains(uri)) { _lookupsInProgress.Add(uri); collectQuotes = true; } } if (collectQuotes) { QuoteCollector.CollectQuotesAsync(topic, culture, uri); } lock (_asyncEnumerators) { _asyncEnumerators.Remove(asyncEnumerator); } }
private IEnumerator<Int32> GetImages(AsyncEnumerator ae) { ae.ThrowOnMissingDiscardGroup(true); // Request all the images asynchronously WebRequest[] requests = new WebRequest[] { WebRequest.Create(_imageUris[0]), WebRequest.Create(m_chkSimFailure.Checked ? _imageUris[2] : _imageUris[1]) }; for(Int32 n = 0; n < requests.Length; n++) requests[n].BeginGetResponse( ae.EndVoid(0, asyncResult => { requests[(Int32) asyncResult.AsyncState].EndGetResponse(asyncResult).Close(); }), n); // Set timeout if specified. Int32 timeout; if(Int32.TryParse(m_txtServerTime.Text, out timeout)) ae.SetCancelTimeout(timeout, null); // WaitAsync for all operations to complete (or timeout) yield return requests.Length; if(ae.IsCanceled()) { m_lblPic1.Text = "Server couldn't process the request in the specified time."; yield break; } for(Int32 n = 0; n < requests.Length; n++) { IAsyncResult result = ae.DequeueAsyncResult(); Int32 reqNum = (Int32) result.AsyncState; Label lbl = (reqNum == 0) ? m_lblPic1 : m_lblPic2; WebRequest request = requests[reqNum]; WebResponse response = null; try { response = request.EndGetResponse(result); lbl.Text = String.Format("Image at {0} is {1:N0} bytes", response.ResponseUri, response.ContentLength); } catch(WebException e) { lbl.Text = String.Format("Error obtaining image at {0}: {1}", request.RequestUri, e.Message); } finally { if(response != null) response.Close(); } } }
private IEnumerator <Int32> GetImages(AsyncEnumerator ae) { ae.ThrowOnMissingDiscardGroup(true); // Request all the images asynchronously WebRequest[] requests = new WebRequest[] { WebRequest.Create(_imageUris[0]), WebRequest.Create(m_chkSimFailure.Checked ? _imageUris[2] : _imageUris[1]) }; for (Int32 n = 0; n < requests.Length; n++) { requests[n].BeginGetResponse( ae.EndVoid(0, asyncResult => { requests[(Int32)asyncResult.AsyncState].EndGetResponse(asyncResult).Close(); }), n); } // Set timeout if specified. Int32 timeout; if (Int32.TryParse(m_txtServerTime.Text, out timeout)) { ae.SetCancelTimeout(timeout, null); } // WaitAsync for all operations to complete (or timeout) yield return(requests.Length); if (ae.IsCanceled()) { m_lblPic1.Text = "Server couldn't process the request in the specified time."; yield break; } for (Int32 n = 0; n < requests.Length; n++) { IAsyncResult result = ae.DequeueAsyncResult(); Int32 reqNum = (Int32)result.AsyncState; Label lbl = (reqNum == 0) ? m_lblPic1 : m_lblPic2; WebRequest request = requests[reqNum]; WebResponse response = null; try { response = request.EndGetResponse(result); lbl.Text = String.Format("Image at {0} is {1:N0} bytes", response.ResponseUri, response.ContentLength); } catch (WebException e) { lbl.Text = String.Format("Error obtaining image at {0}: {1}", request.RequestUri, e.Message); } finally { if (response != null) { response.Close(); } } } }
static IEnumerator <int> ClientFiber(AsyncEnumerator ae, TcpClient clientSocket) { Console.WriteLine("ClientFibers ++{0}", Interlocked.Increment(ref clients)); try { // original code to do handshaking and connect to remote host var ns1 = clientSocket.GetStream(); var r1 = new BinaryReader(ns1); var w1 = new BinaryWriter(ns1); if (!(r1.ReadByte() == 5 && r1.ReadByte() == 1)) { yield break; } var c = r1.ReadByte(); for (int i = 0; i < c; ++i) { r1.ReadByte(); } w1.Write((byte)5); w1.Write((byte)0); if (!(r1.ReadByte() == 5 && r1.ReadByte() == 1)) { yield break; } if (r1.ReadByte() != 0) { yield break; } byte[] ipAddr = null; string hostname = null; var type = r1.ReadByte(); switch (type) { case 1: ipAddr = r1.ReadBytes(4); break; case 3: hostname = Encoding.ASCII.GetString(r1.ReadBytes(r1.ReadByte())); break; case 4: throw new Exception(); } var nhport = r1.ReadInt16(); var port = IPAddress.NetworkToHostOrder(nhport); var socketout = new TcpClient(); if (hostname != null) { socketout.Connect(hostname, port); } else { socketout.Connect(new IPAddress(ipAddr), port); } w1.Write((byte)5); w1.Write((byte)0); w1.Write((byte)0); w1.Write(type); switch (type) { case 1: w1.Write(ipAddr); break; case 3: w1.Write((byte)hostname.Length); w1.Write(Encoding.ASCII.GetBytes(hostname), 0, hostname.Length); break; } w1.Write(nhport); using (var ns2 = socketout.GetStream()) { var forwardAe = new AsyncEnumerator() { SyncContext = null }; forwardAe.BeginExecute( ForwardingFiber(forwardAe, ns1, ns2), ae.EndVoid(0, forwardAe.EndExecute), null); yield return(1); if (ae.IsCanceled()) { yield break; } forwardAe.EndExecute(ae.DequeueAsyncResult()); } } finally { Console.WriteLine("ClientFibers --{0}", Interlocked.Decrement(ref clients)); } }
static IEnumerator <int> ForwardingFiber(AsyncEnumerator ae, NetworkStream inputStream, NetworkStream outputStream) { while (!ae.IsCanceled()) { byte[] outputRead = new byte[bufsize], outputWrite = new byte[bufsize]; byte[] inputRead = new byte[bufsize], inputWrite = new byte[bufsize]; // start off output and input reads. // NB ObjectDisposedExceptions can be raised here when a socket is closed while an async read is in progress. outputStream.BeginRead(outputRead, 0, bufsize, ae.End(1, ar => outputStream.EndRead(ar)), Operation.OutboundRead); inputStream.BeginRead(inputRead, 0, bufsize, ae.End(1, ar => inputStream.EndRead(ar)), Operation.InboundRead); var pendingops = 2; while (!ae.IsCanceled()) { // wait for the next operation to complete, the state object passed to each async // call can be used to find out what completed. if (pendingops == 0) { yield break; } yield return(1); if (!ae.IsCanceled()) { int byteCount; var latestEvent = ae.DequeueAsyncResult(); var currentOp = (Operation)latestEvent.AsyncState; if (currentOp == Operation.InboundRead) { byteCount = inputStream.EndRead(latestEvent); if (byteCount == 0) { pendingops--; outputStream.Close(); continue; } Array.Copy(inputRead, outputWrite, byteCount); outputStream.BeginWrite(outputWrite, 0, byteCount, ae.EndVoid(1, outputStream.EndWrite), Operation.OutboundWrite); inputStream.BeginRead(inputRead, 0, bufsize, ae.End(1, ar => inputStream.EndRead(ar)), Operation.InboundRead); } else if (currentOp == Operation.OutboundRead) { byteCount = outputStream.EndRead(latestEvent); if (byteCount == 0) { pendingops--; inputStream.Close(); continue; } Array.Copy(outputRead, inputWrite, byteCount); inputStream.BeginWrite(inputWrite, 0, byteCount, ae.EndVoid(1, inputStream.EndWrite), Operation.InboundWrite); outputStream.BeginRead(outputRead, 0, bufsize, ae.End(1, ar => outputStream.EndRead(ar)), Operation.OutboundRead); } else if (currentOp == Operation.InboundWrite) { inputStream.EndWrite(latestEvent); } else if (currentOp == Operation.OutboundWrite) { outputStream.EndWrite(latestEvent); } } } } }
private IEnumerator<Int32> DownloadImages(AsyncEnumerator ae) { ae.ThrowOnMissingDiscardGroup(true); GetImages.IsEnabled = false; Cancel.IsEnabled = true; WebRequest[] requests = new WebRequest[] { WebRequest.Create(UriHelper.ConvertRelativeUriStringToAbsolute("Images/Wintellect.jpg")), WebRequest.Create(UriHelper.ConvertRelativeUriStringToAbsolute("Images/JeffreyRichter.jpg")), }; for (Int32 requestNum = 0; requestNum < requests.Length; requestNum++) { requests[requestNum].BeginGetResponse( ae.EndVoid(0, asyncResult => { requests[requestNum].EndGetResponse(asyncResult).Close(); }), requestNum); } for (Int32 resultNum = 0; resultNum < requests.Length; resultNum++) { yield return 1; if (ae.IsCanceled()) break; IAsyncResult asyncResult = ae.DequeueAsyncResult(); Int32 index = (Int32)asyncResult.AsyncState; try { using (WebResponse response = requests[index].EndGetResponse(asyncResult)) { using (Stream stream = response.GetResponseStream()) { BitmapImage bitmapImage = new BitmapImage(); bitmapImage.SetSource(stream); m_images[index].Source = bitmapImage; } } } catch (WebException e) { m_textboxes[index].Text = "Failed: " + e.Message; } } GetImages.IsEnabled = true; Cancel.IsEnabled = false; }
// Because SyncContext is set, all the iterator code runs on the GUI thread private IEnumerator<Int32> GetWebData(AsyncEnumerator ae, String[] uris) { ToggleStartAndCancelButtonState(false); m_lbResults.Items.Clear(); // Auto-cancel after 5 seconds if the user desires if (m_chkAutoCancel.Checked) ae.SetCancelTimeout(5000, ae); // Issue several web requests (all in discard group 0) simultaneously foreach (String uri in uris) { WebRequest webRequest = WebRequest.Create(uri); // If the AsyncEnumerator is canceled, DiscardWebRequest cleans-up // any outstanding operations as they complete in the future webRequest.BeginGetResponse(ae.EndVoid(0, DiscardWebRequest), webRequest); } yield return uris.Length; // Process the completed web requests after all complete String resultStatus; // Ultimate result of processing shown to user // Check if iterator was canceled Object cancelValue; if (ae.IsCanceled(out cancelValue)) { // Tell the AE to auto-cleanup any operations issued as part of discard group 0 ae.DiscardGroup(0); // Note: In this example calling DiscardGroup above is not mandatory // because the whole iterator is stopping execution; causing all // discard groups to be discarded automatically. resultStatus = (cancelValue == ae) ? "Timeout" : "User canceled"; goto Complete; } // Iterator wasn't canceled, process all the completed operations for (Int32 n = 0; n < uris.Length; n++) { // Grab the result of a completed web request IAsyncResult result = ae.DequeueAsyncResult(); // Get the WebRequest object used to initate the request // (see BeginGetResponse's last argument above) WebRequest webRequest = (WebRequest)result.AsyncState; // Build the String showing the result of this completed web request String s = "URI=" + webRequest.RequestUri + ", "; try { using (WebResponse webResponse = webRequest.EndGetResponse(result)) { s += "ContentLength=" + webResponse.ContentLength; } } catch (WebException e) { s += "Error=" + e.Message; } m_lbResults.Items.Add(s); // Add result of operation to listbox } resultStatus = "All operations completed."; Complete: // All operations have completed or cancelation occurred, tell user MessageBox.Show(this, resultStatus); // Reset everything so that the user can start over if they desire m_ae = null; // Reset since we're done ToggleStartAndCancelButtonState(true); }
private IEnumerator <int> ProcessCollectQuotes(AsyncEnumerator asyncEnumerator, string topic, CultureInfo culture, Uri uri, AssignQuotePageDataDelegate assignQuotesDelegate) { Uri quoteSourceUri = GetQuoteSourceUri(culture, topic); Util.BeginFetchXmlPage(quoteSourceUri, asyncEnumerator.End(AsyncEnumeratorDiscardGroup, Util.EndFetchXmlPage), null); yield return(1); if (asyncEnumerator.IsCanceled()) { yield break; } string contents; try { XDocument xDocument = Util.EndFetchXmlPage(asyncEnumerator.DequeueAsyncResult()); if (xDocument == null) { throw new NullReferenceException(); } // extracting the page contents contents = GetXmlPageContents(xDocument); } catch (Exception ex) { OnErrorCollectingQuotes(new ErrorCollectingQuotesEventArgs(topic, culture, uri, ex)); yield break; } IAsyncResult getQuotesResult = BeginParsePageContentsAndExtractQuotes(topic, culture, contents, null, asyncEnumerator.End(AsyncEnumeratorDiscardGroup, EndParsePageContentsAndExtractQuotes), null); IAsyncResult getTopicTranslationsResult = BeginExtractTopicTranslations(contents, asyncEnumerator.End(AsyncEnumeratorDiscardGroup, EndExtractTopicTranslations), null); yield return(2); if (asyncEnumerator.IsCanceled()) { yield break; } try { TopicTranslation[] topicTranslations = EndExtractTopicTranslations(getTopicTranslationsResult); SelectableQuoteCollection quotes = EndParsePageContentsAndExtractQuotes(getQuotesResult); if (quotes.Count == 0) { OnNoQuotesCollected(new NoQuotesCollectedEventArgs(topic, culture, uri)); // Change by Ming Slogar on 26Apr2014 at 20:25 // Reason: The following line prevents the topic from being returned // when it has no listed quotes. //yield break; } assignQuotesDelegate.Invoke(quotes, topicTranslations); } catch (TopicAmbiguousException ex) { OnTopicAmbiguous(new TopicAmbiguousEventArgs(topic, culture, uri, ex.TopicChoices)); yield break; } catch (Exception ex) { OnErrorCollectingQuotes(new ErrorCollectingQuotesEventArgs(topic, culture, uri, ex)); yield break; } finally { // cleanup asyncEnumerator.DequeueAsyncResult(); asyncEnumerator.DequeueAsyncResult(); lock (asyncEnumerator) { _asyncEnumerators.Remove(asyncEnumerator); } } }