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.