Skip to content

Instantly share code, notes, and snippets.

@christophercurrie
Last active December 18, 2015 15:59
Show Gist options
  • Save christophercurrie/5808161 to your computer and use it in GitHub Desktop.
Save christophercurrie/5808161 to your computer and use it in GitHub Desktop.
Various attempts at implementing an asynchronous download processor.
internal class BoundedAsyncDownload1
{
private const int MaxRequests = 4;
private void HandleResponse(WebResponse response)
{ }
private void CreateRequest(ConcurrentQueue<WebRequest> queue)
{
WebRequest request;
if (!queue.TryDequeue(out request)) return;
request.BeginGetResponse(ar =>
{
CreateRequest(queue);
HandleResponse(request.EndGetResponse(ar));
}, null);
}
public void DownloadList(IEnumerable<Uri> uris)
{
var requests = new ConcurrentQueue<WebRequest>(uris.Select(WebRequest.Create));
for (var i = 0; i < MaxRequests; ++i)
{
CreateRequest(requests);
}
}
}
public static class WebRequestAsync
{
public static Task<WebResponse> GetResponseAsync(this WebRequest request, object state = null)
{
return Task<WebResponse>.Factory.FromAsync(request.BeginGetResponse, request.EndGetResponse, state);
}
}
internal class BoundedAsyncDownload2
{
private const int MaxRequests = 4;
private void HandleResponse(WebResponse response)
{ }
private void CreateRequest(ConcurrentQueue<WebRequest> queue)
{
WebRequest request;
if (!queue.TryDequeue(out request)) return;
request.GetResponseAsync().ContinueWith(task =>
{
CreateRequest(queue);
HandleResponse(task.Result);
});
}
public void DownloadList(IEnumerable<Uri> uris)
{
var requests = new ConcurrentQueue<WebRequest>(uris.Select(WebRequest.Create));
for (var i = 0; i < MaxRequests; ++i)
{
CreateRequest(requests);
}
}
}
internal class BoundedAsyncDownload3
{
private const int MaxRequests = 4;
private class State
{
public TaskCompletionSource<Object> Tcs;
public int TotalRequests;
}
private void HandleResponse(WebResponse response)
{
}
private void CreateRequest(ConcurrentQueue<WebRequest> queue, State state)
{
WebRequest request;
if (!queue.TryDequeue(out request)) return;
request.GetResponseAsync().ContinueWith(task =>
{
if (Interlocked.Decrement(ref state.TotalRequests) <= 0)
state.Tcs.SetResult(null);
CreateRequest(queue, state);
HandleResponse(task.Result);
});
}
public Task DownloadList(IEnumerable<Uri> uris)
{
var requests = new ConcurrentQueue<WebRequest>(uris.Select(WebRequest.Create));
var state = new State {Tcs = new TaskCompletionSource<object>(), TotalRequests = requests.Count};
for (var i = 0; i < MaxRequests; ++i)
{
CreateRequest(requests, state);
}
return state.Tcs.Task;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment