Last active
December 18, 2015 15:59
-
-
Save christophercurrie/5808161 to your computer and use it in GitHub Desktop.
Various attempts at implementing an asynchronous download processor.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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