简体   繁体   中英

C# Named Tasks What's the proper way?

I am trying to work on concatenated tasks.

My idea is to have something similar to the next code, but VS marks my code as:

cannot convert from 'System.Threading.Tasks.Task' to 'System.Action' in Argument1

Whats the proper way to syntax this ?

public void startAllTasks()
{
    Task task1 = new Task(() => GetLocalDbRecords());
    Task task2 = new Task(() => CreatePlainTextFile());
    Task task3 = new Task(() => SendToWS());
    task1.ContinueWith(task2);
    task2.ContinueWith(task3);
    task1.Start();
}

I have my desired result by using the next code (I know I must optimize it), but my idea is to improve it by using the "ContinueWith" and one CancellationToken, but no luck yet

public void startAllTasks()
        {
            records = 0;
            stopFlag = false;
            tasksRunning = new Dictionary<int, bool>();
            tasksRunning.Add(1, false);
            tasksRunning.Add(2, false);
            tasksRunning.Add(3, false);
            currentStep = 0;
            while (!stopFlag)
            {
                if (currentStep == 0 && !tasksRunning[1])
                {
                    tasksRunning[1] = true;
                    Task task1 = new Task(() => this.GetLocalDbRecords());
                    task1.Start();
                }
                if (currentStep == 1 && !tasksRunning[2])
                {
                    tasksRunning[2] = true;
                    Task task2 = new Task(() => this.CreatePlainTextFile());
                    task2.Start();
                }
                if (currentStep == 3 && !tasksRunning[3])
                {
                    tasksRunning[3] = true;
                    Task task3 = new Task(() => this.SendToWS());
                    task3.Start();
                }
                Thread.Sleep(100);
            }
        }

That is the proper syntax (explanation below):

Task task1 = new Task(() => GetLocalDbRecords());
Task task2 = new Task(() => CreatePlainTextFile());
Task task3 = new Task(() => SendToWS());
task1.ContinueWith(x => task2.Start());
task2.ContinueWith(x => task3.Start());
task1.Start();

Note that the ContinueWith method does not receive a Task it receives an Action<Task> , this Action is invoked after the first Task is complete and it will receive the first Task as an argument so you can use it's return value for example.

You can also use this fluent syntax of Task.Factory which also removes your need to use Task.Start() :

Task.Factory.StartNew(GetLocalDbRecords)
    .ContinueWith(x => CreatePlainTextFile())
    .ContinueWith(x => SendToWS())
    .Wait();

In order to use a CancellationToken you need to use a CancellationTokenSource and it works like that:

From MSDN's Page about Task cancellation

1) Create and start a cancelable task.

2) Pass a cancellation token to your user delegate and optionally to the task instance.

3) Notice and respond to the cancellation request in your user delegate.

4) Optionally notice on the calling thread that the task was canceled.

And a code example:

CancellationTokenSource tokenSource = new CancellationTokenSource();
CancellationToken token = tokenSource.Token;

Task.Factory.StartNew(GetLocalDbRecords)
    .ContinueWith(x => CreatePlainTextFile(), tokenSource.Token)
    .ContinueWith(x => SendToWS(), tokenSource.Token);

tokenSource.Cancel();
bool cancelationRequested = token.IsCancellationRequested; //Value will be true.

Task s will not stop automatically when you use tokenSource.Cancel(); as they might run on the same Thread which invoked them and they must be aware of the CancellationToken and poll IsCancellationRequested if they wish to stop according to it, however, if a Task or its consecutive Task s are trying to start when the CancellationToken is already been requested to cancel, the Task or its consecutive Task s will not be invoked in the first place.

Also, you can use CancellationTokenSource.CancelAfter(TimeSpan) in order to put a timeout before cancelling.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM