.netmultithreadingbackgroundworker

Using .NET BackgroundWorker class in console app


I am relatively new to .NET programming and multithreading in general, and was wondering if it is ok to use .NET provided BackgroundWorker to spawn off worker threads to do some work in a console application? From the various documentation online, I see that intent for this class is more for UI oriented applications, where you want to do some work in background, but keep the UI responsive, and report progress, cancelling processing if needed etc.

In my case, basically I have a controller class where I want to spawn off multiple worker threads to do some processing (limiting the max number of worker threads spawned using a semaphore). Then I want my controller class to block until all the threads have completed processing. So after I start a worker thread to do some work, I want the thread to be able to notify the controller thread when processing is complete. I see that I can use the background worker class, and handle events DoWork and RunWorkerCompleted to accomplish this, however was wondering if this is good idea? Are there better ways to achieve this?


Solution

  • This won't work in a Console Application, since SynchronizationContext.Current will never be initialized. This is initialized by Windows Forms or WPF for you, when you're using a GUI application.

    That being said, there's no reason to do this. Just use ThreadPool.QueueUserWorkItem, and a reset event (ManualResetEvent or AutoResetEvent) to trap the completion state, and block your main thread.


    Edit:

    After seeing some of the OP comments, I thought I'd add this.

    The "nicest" alternative, in my opinion, would be to get a copy of the Rx Framework, since it includes a backport of the TPL in .NET 4. This would allow you to use the overload of Parallel.ForEach which provides the option of supplying a ParallelOptions instance. This will allow you to restrict the total number of concurrent operations, and handle all of the work for you:

    // using collection of work items, such as: List<Action<object>> workItems;
    var options = new ParallelOptions();
    options.MaxDegreeOfParallelism = 10; // Restrict to 10 threads, not recommended!
    
    // Perform all actions in the list, in parallel
    Parallel.ForEach(workItems, options, item => { item(null); });
    

    However, using Parallel.ForEach, I'd personally let the system manage the degree of parallelism. It will automatically assign an appropriate number of threads (especially when/if this moves to .NET 4).