Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I had previously asked this question on SO. The answer pointed me towards using the task parallel library for multiple parallel downloads. I'm not actually utilizing this exact code, but it got me to rethink my design.

The one open issue that wasn't really addressed (and I didn't ask it), cancelling the a local WebClient. It isn't as simple as just calling WebClient.CancelASync(); since the scope of WebClient is long gone by the time you need to cancel.

This isn't my code or even how I am approaching the problem, but just part of the test example I put together to see how this works. It seems to work, although it means having to wait for an event callback before the cancel is called. So I was wondering if there was another alternative.

private bool pendingCancel = false;
private Queue<Uri> queue = LoadQueue();

public void ASyncDownload()
{
    if (queue.Count == 0) return;

    var uri = queue.Dequeue();

    WebClient client = new WebClient();
    client.DownloadProgressChanged
        += (sender, e) =>
        {
            if (pendingCancellation)
            {
                ((WebClient)sender).CancelAsync();
                return;
            }

            //do something to report progress
        };

    client.DownloadDataCompleted
        += (sender, e) =>
        {
            if (!e.Cancelled || pendingCancel)
            {
                if (e.Error == null)
                {
                    // do something with e.Results
                }
                else
                {
                    // report error
                }
            }
            else
            {
                // report cancellation
            }
        };

    client.DownloadDataAsync(uri);
}

My thought process is for any long running downloads, waiting until the next item in the queue to exit would not be appropriate, so the idea would be to call CancelASync() on the sender of the DownloadProgressChanged event handler.

Is this the best alternative short of putting a webClient field in the class? And are there dangers or possible unpredictable behavior that I have not found in my testing?

share|improve this question
1  
Why are you trying to avoid using a field? That's exactly what they're for: storing objects that are needed for more than just one method call. – svick Aug 17 '12 at 11:52
    
@svick In the end, I'm not trying to avoid anything, but I see similar patterns in other code and I am trying to understand if it is possible to cancel this type of async operation – psubsee2003 Aug 17 '12 at 13:15

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.