HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Concurrent blocking Tasks in a BackgroundWorker

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
backgroundworkertasksconcurrentblocking

Problem

I'm using a StaTaskScheduler (TPL extension) to open some web browser windows simultaneously and navigate to different sites (using WatiN, but it might as well just be a WebBrowser).

In my example below I'm running 5 concurrent browsers. Works fine, but it locked the UI thread, so I wrapped my tasks in a BackgroundWorker. Seems like it does the job, but is it the correct way of handling the issue? Do I need to dispose the worker once I'm done? And finally, is lock (ret) the correct way of keeping ret thread safe?

StaTaskScheduler sta = new StaTaskScheduler(5);
BackgroundWorker bw = new BackgroundWorker();

bw.DoWork += (s, ea) =>
{
    List ret = new List();

    lock (ret)

    Task.WaitAll(Util.GetList().Select(row => Task.Factory.StartNew(() =>
    {

        IEnumerable result = DoUiLockingWork(row.Item1, row.Item2);
        ret.AddRange(result);

    }, CancellationToken.None, TaskCreationOptions.None, sta)).ToArray());

    ea.Result = ret;
};

bw.RunWorkerCompleted += (s, ea) =>
{
    List result = ea.Result as List;

    if (result != null) 
        Debug.WriteLine(result.Count);
};

bw.RunWorkerAsync();

Solution

I would go with Task-based method (if you're using .Net 4.5) instead of the BackgroundWorker. That will sort out most of your problems.

Something in the vicinities of

async Task> yourJobAsync(...)
{
    var results = await Task.Run ( () =>
    {
        //your job.
        return jobResults
    });
    return  yourJobAsyncResults
}

Code Snippets

async Task<List<T>> yourJobAsync(...)
{
    var results = await Task.Run ( () =>
    {
        //your job.
        return jobResults
    });
    return  yourJobAsyncResults
}

Context

StackExchange Code Review Q#54106, answer score: 9

Revisions (0)

No revisions yet.