Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET 4.0 Threading.Tasks

I've recently started working on a new application which will utilize task parallelism. I have just begun writing a tasking framework, but have recently seen a number of posts on SO regarding the new System.Threading.Tasks namespace which may be useful to me (and I would rather use an existing framework than roll my own).

However looking over MSDN I haven't seen how / if, I can implement the functionality which I'm looking for:

  • Dependency on other tasks completing.
  • Able to wait on an unknown number of tasks preforming the same action (maybe wrapped in the same task object which is invoked multiple times)
  • Set maximum concurrent instances of a task since they use a shared resource there is no point running more than one at once
  • Hint at priority, or scheduler places tasks with lower maximum concurrent instances at a higher priority (so as to keep said resource in use as much as possible)
  • Edit ability to vary the priority of tasks which are preforming the same action (pretty poor example but, PredictWeather (Tommorrow) will have a higher priority than PredictWeather (NextWeek))

Can someone point me towards an example / tell me how I can achieve this? Cheers.

C# Use Case: (typed in SO so please for give any syntax errors / typos)

**note Do() / DoAfter() shouldn't block the calling thread*

class Application ()
{

    Task LeafTask = new Task (LeafWork) {PriorityHint = High, MaxConcurrent = 1};
    var Tree = new TaskTree (LeafTask); 

    Task TraverseTask = new Task (Tree.Traverse); 
    Task WorkTask = new Task (MoreWork); 
    Task RunTask = new Task (Run);

    Object SharedLeafWorkObject = new Object ();

    void Entry ()
    {
        RunTask.Do ();
        RunTask.Join (); // Use this thread for task processing until all invocations of RunTask are complete
    }

    void Run(){                           
        TraverseTask.Do ();

        // Wait for TraverseTask to make sure all leaf tasks are invoked before waiting on them 
        WorkTask.DoAfter (new [] {TraverseTask, LeafTask});

        if (running){
            RunTask.DoAfter (WorkTask);   // Keep at least one RunTask alive to prevent Join from 'unblocking'
        }
        else    
        {
            TraverseTask.Join();
            WorkTask.Join ();
        }
    } 

    void LeafWork (Object leaf){
        lock (SharedLeafWorkObject)  // Fake a shared resource
        {
            Thread.Sleep (200); // 'work'
        } 
    }

    void MoreWork ()
    {
        Thread.Sleep (2000); // this one takes a while
    }
}


class TaskTreeNode<TItem>
{
    Task LeafTask; // = Application::LeafTask
    TItem Item;

    void Traverse ()
    {
        if (isLeaf)
        { 
            // LeafTask set in C-Tor or elsewhere
            LeafTask.Do(this.Item);

            //Edit
            //LeafTask.Do(this.Item, this.Depth); // Deeper items get higher priority
            return;
        }
        foreach (var child in this.children)
        {
            child.Traverse (); 
        }
    }
}

1 Answers

There are numerous examples here:

http://code.msdn.microsoft.com/ParExtSamples

There's a great white paper which covers a lot of the details you mention above here:

"Patterns for Parallel Programming: Understanding and Applying Parallel Patterns with the .NET Framework 4"

http://www.microsoft.com/downloads/details.aspx?FamilyID=86b3d32b-ad26-4bb8-a3ae-c1637026c3ee&displaylang=en

Off the top of my head I think you can do all the things you list in your question.

  • Dependencies etc: Task.WaitAll(Task[] tasks)
  • Scheduler: The library supports numerous options for limiting number of threads in use and supports providing your own scheduler. I would avoid altering the priority of threads if at all possible. This is likely to have negative impact on the scheduler, unless you provide your own.
like image 200
Ade Miller Avatar answered Apr 11 '26 10:04

Ade Miller



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!