Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8343617
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 9, 20262026-06-09T06:07:18+00:00 2026-06-09T06:07:18+00:00

Thread-Safety is not an aspect that I have worried about much as the simple

  • 0

Thread-Safety is not an aspect that I have worried about much as the simple apps and libraries I have written usually only run on the main thread, or do not directly modified properties or fields in any classes that I needed to worry about before.

However, I have started working on a personal project that I am using a WebClient to download data asynchronously from a remote server. There is a Queue<Uri> that contains a pre-built queue of a series of URI’s to download data.

So consider the following snippet (this is not my real code, but something I am hoping illustrates my question:

private WebClient webClient = new WebClient();
private Queue<Uri> requestQueue = new Queue<Uri>();

public Boolean DownloadNextASync()
{
    if (webClient.IsBusy)
        return false;

    if (requestQueue.Count == 0)
        return false

    var uri = requestQueue.Dequeue();

    webClient.DownloadDataASync(uri);

    return true;

}

If I am understanding correctly, this method is not thread safe (assuming this specific instance of this object is known to multiple threads). My reasoning is webClient could become busy during the time between the IsBusy check and the DownloadDataASync() method call. And also, requestQueue could become empty between the Count check and when the next item is dequeued.

My question is what is the best way to handle this type of situation to make it thread-safe?

This is more of an abstract question as I realize for this specific method that there would have to be an exceptionally inconvenient timing for this to actually cause a problem, and to cover that case I could just wrap the method in an appropriate try-catch since both pieces would throw an exception. But is there another option? Would a lock statement be applicable here?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-09T06:07:20+00:00Added an answer on June 9, 2026 at 6:07 am

    If you’re targeting .Net 4.0, you could use the Task Parallel Library for help:

    var queue = new BlockingCollection<Uri>();
    var maxClients = 4;
    
    // Optionally provide another producer/consumer collection for the data
    // var data = new BlockingCollection<Tuple<Uri,byte[]>>();
    
    // Optionally implement CancellationTokenSource
    
    var clients = from id in Enumerable.Range(0, maxClients)
                  select Task.Factory.StartNew(
        () =>
        {
            var client = new WebClient();
            while (!queue.IsCompleted)
            {
                Uri uri;
                if (queue.TryTake(out uri))
                {
                    byte[] datum = client.DownloadData(uri); // already "async"
                    // Optionally pass datum along to the other collection
                    // or work on it here
                }
                else Thread.SpinWait(100);
            }
        });
    
    // Add URI's to search
    // queue.Add(...);
    
    // Notify our clients that we've added all the URI's
    queue.CompleteAdding();
    
    // Wait for all of our clients to finish
    clients.WaitAll();
    

    To use this approach for progress indication you can use TaskCompletionSource<TResult> to manage the Event based parallelism:

    public static Task<byte[]> DownloadAsync(Uri uri, Action<double> progress)
    {
        var source = new TaskCompletionSource<byte[]>();
        Task.Factory.StartNew(
            () =>
            {
                var client = new WebClient();
                client.DownloadProgressChanged
                    += (sender, e) => progress(e.ProgressPercentage);
                client.DownloadDataCompleted
                    += (sender, e) =>
                    {
                        if (!e.Cancelled)
                        {
                            if (e.Error == null)
                            {
                                source.SetResult((byte[])e.Result);
                            }
                            else
                            {
                                source.SetException(e.Error);
                            }
                        }
                        else
                        {
                            source.SetCanceled();
                        }
                   };
            });
    
        return source.Task;
    }
    

    Used like so:

    // var urls = new List<Uri>(...);
    // var progressBar = new ProgressBar();
    
    Task.Factory.StartNew(
        () =>
        {
           foreach (var uri in urls)
           {
               var task = DownloadAsync(
                   uri,
                   p =>
                       progressBar.Invoke(
                           new MethodInvoker(
                           delegate { progressBar.Value = (int)(100 * p); }))
                   );
    
               // Will Block!
               // data = task.Result;
           } 
        });
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I replied to a question earlier about thread safety which did not get a
I have recently inherited a large Java Application that has almost no Thread safety
I have a question about thread safety. From what I have been told, SimpleDateFormat
Not sure if threads safety even applies to ||= . Was originally reading about
In many MSDN documents, this is written under the Thread Safety heading; Any public
This is about thread safety of std::map . Now, simultaneous reads are thread-safe but
For thread-safety reasons it is argumented: Do not allow the this reference to escape
According to Apple Docs NSCalendar is not thread-safe . How can I ensure thread-safety
ConcurrentHashMap is fully interoperable with Hashtable in programs that rely on its thread safety
The regular Thread Safety section of the MSDN documentation for StringBuilder states that: ...any

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.