Cancel tasks, share status, and so on in parallel programming.

Source: Internet
Author: User

Cancel tasks, share status, and so on in parallel programming.

 

In the face of mutually independent data or mutually independent tasks, it may be the time when Parallel debuted.

 

For example, a set of boxes allows the box to rotate at a certain angle.

 

void RotateBox(IEnumerable<Box> boxes, float degree)
{
    Parallel.ForEach(boxes, box => box.Rotate(degree));
}

 

What if an exception occurs in a parallel task and the problematic task needs to be terminated?

 

Parallel. ForEach provides us with an overload method to control whether the task continues.

 

void RotateBoxes(IEnumerable<Box> boxes)
{
    Parallel.ForEach(boxes, (box, state) => {
        if(!box.IsInvertible)
        {
            state.Stop();
        }
        else
        {
            box.Invert();
        }
    });
}

 

What if I want to cancel the entire parallel task?

 

Parallel. ForEach also provides us with an overload method that can receive a ParallelOption parameter and cancel the entire Parallel process by setting the CancellationToken attribute of ParallelOption.

 

void RotateBoxes(IEnumerable<Box> boxes,float degrees, CancellationToken token)
{
    Paralle.ForEach(boxes, 
    new ParallelOptions{CancellationToken=token},
    box => box.Rotate(degrees));
}

 

Generally, a global CancellationTokenSource variable is defined first.

 

Static CancellationTokenSource token = new CancellationTokenSource ();

 

Then, cancel the settings in a parallel task.

 

Token. Cancel ();

 

Finally, assign the token to the CancellationToken attribute of the preceding method.

 

How do parallel tasks share the status and a variable?

 

int InvertBoxes(IEnumerable<Box> boxes)
{
Object mutex = new object (); // used to lock
Int nonInvertibleCount = 0; // variable shared by each task
    Paralle.ForEach(boxes, box =>{
        if(box.IsInvertible){
            box.Invert();
        }
        else
        {
            lock(mutex)
            {
                ++nonInvertibleCount;
            }
        }
    });
    return nonInvertibleCount;
}

 

It can be seen that a thread lock is required for variables shared by parallel threads to prevent multiple threads from simultaneously operating shared variables.

 

In addition, Parallel. ForEach provides an overload. The localFinally parameter receives a delegate type and shares a variable with the Parallel task. For example:

 

static int ParallelSum(IEnumerable<int> values)
{
    object mutex = new object();
    int result = 0;
    Parallel.ForEach(
        source: values,
        LocalInit: () => 0,
        body: (item, state, localVlaue) => localValue + item,
        localFinally: localValue => {
            lock(mutex)
            {
                result += localValue;
            }
        }
    );
    return result;
}

 

Of course, do not forget that PLINQ also supports Parallelism:

 

static int ParalleSum(IEnumerable<int> values)
{
    return values.AsParallel().Sum();
}

 

The Aggregate method of PLINQ can also be implemented:

 

static int ParallelSum(IEnumerable<int> values)
{
    return values.AsParallel().Aggregate(
        seed: 0,
        func: (sum, item) => sum + item;
    );
}

 

The above is the processing of mutually independent data.

 

So how can we handle multiple independent tasks?

 

You can use the Parallel. Invoke method.

 

static voiD ProcessArray(double[] array)
{
    Parallel.Invoke(
        () => ProcessPartialArray(array, 0, array.Length/2),
        () => ProcessPartialArray(array, array.Length/2, array.Length)
    );
}
static void ProcessPartialArray(double[] array, int begin, int end)
{}

 

The Parallel. Invoke method also allows an Action or this method to be executed multiple times.

 

static void Do20(Action action)
{
// Execute an Action 20 times
    Action[] actions = Enumerable.Repeat(action, 20).ToArray();
    Parallel.Invoke(actions);
}

 

The Parallel. Invoke method also provides an overload to receive parameters of the ParallelOption type, which is used to control the cancellation of the entire Parallel process.

 

static void Do20(Action action)
{
// Execute an Action 20 times
    Action[] actions = Enumerable.Repeat(action, 20).ToArray();
    Parallel.Invoke(new ParallelOptions{CancellationToken = token},actions);
}

 

Reference: C # typical concurrent programming instance

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.