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

Run control tasks asynchronously using TPL

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

Problem

One of my classes regularly triggers one of two asynchronous operations: a "turn on" and a "turn off" that each take about a second. I'm using this method below to make sure that they don't run simultaneously. It doesn't seem very elegant to me. Is there some better way to do this? I'm using .NET 4.0, but I would like to know if there are any .NET 4.5 methods that make this easier.

private Task _changingControl;
private void RunControlTask(Task newTask)
{
    var cc = _changingControl;
    if (cc == null || cc.IsCompleted)
    {
        _changingControl = newTask;
        newTask.Start();
    }
    else
    {
        _changingControl = cc.ContinueWith(old =>
        {
            newTask.RunSynchronously();
            newTask.Dispose(); // only needed if we manually wait for it to finish
        });
    }
}

Solution

First, some notes about your code:

  • Using Tasks that are first created and later started usually doesn't make much sense. To represent some work to be done, just use a delegate.



  • Tasks almost never need to be Disposed.



Now, I think that what you want to do would be easiest to achieve using ActionBlock from TPL Dataflow. When you want to perform the operation, you would send a message to the block and the action in the block would execute it. ActionBlock already performs all synchronization necessary to make sure only one operation executes at a time.

ActionBlock _changeControlBlock = new ActionBlock(ChangeControl);

private void ChangeControl(bool on)
{
    if (on)
    {
        // turn on
    }
    else
    {
        // turn off
    }
}

public void TurnOn()
{
    _changeControlBlock.Post(true);
}

public void TurnOn()
{
    _changeControlBlock.Post(false);
}

Code Snippets

ActionBlock<bool> _changeControlBlock = new ActionBlock<bool>(ChangeControl);

private void ChangeControl(bool on)
{
    if (on)
    {
        // turn on
    }
    else
    {
        // turn off
    }
}

public void TurnOn()
{
    _changeControlBlock.Post(true);
}

public void TurnOn()
{
    _changeControlBlock.Post(false);
}

Context

StackExchange Code Review Q#41230, answer score: 3

Revisions (0)

No revisions yet.