[英]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:我的想法是有一些类似于下一个代码的东西,但 VS 将我的代码标记为:
cannot convert from 'System.Threading.Tasks.Task' to 'System.Action' in Argument1
无法在 Argument1 中从“System.Threading.Tasks.Task”转换为“System.Action”
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我通过使用下一个代码得到了我想要的结果(我知道我必须优化它),但我的想法是通过使用“ContinueWith”和一个 CancellationToken 来改进它,但还没有运气
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.请注意,
ContinueWith
方法不会接收一个Task
它接收一个Action<Task>
,这个Action
在第一个Task
完成后被调用,它将接收第一个Task
作为参数,因此您可以使用它的返回值。
You can also use this fluent syntax of Task.Factory
which also removes your need to use Task.Start()
:您还可以使用
Task.Factory
这种流畅语法,这也消除了您使用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:为了使用
CancellationToken
您需要使用CancellationTokenSource
,它的工作原理如下:
From MSDN's Page about Task
cancellation来自MSDN 的关于取消
Task
的页面
1) Create and start a cancelable task.
1) 创建并启动一个可取消的任务。
2) Pass a cancellation token to your user delegate and optionally to the task instance.
2) 将取消令牌传递给您的用户委托,并可选择传递给任务实例。
3) Notice and respond to the cancellation request in your user delegate.
3) 在您的用户委托中通知并响应取消请求。
4) Optionally notice on the calling thread that the task was canceled.
4) 可选地在调用线程上通知任务被取消。
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();
使用
tokenSource.Cancel();
时, Task
不会自动停止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.因为它们可能在调用它们的同一个
Thread
上运行,并且它们必须知道CancellationToken
并轮询IsCancellationRequested
如果他们希望根据它停止,但是,如果Task
或其连续Task
试图在CancellationToken
已经被请求取消时,首先不会调用Task
或其连续的Task
。
Also, you can use CancellationTokenSource.CancelAfter(TimeSpan)
in order to put a timeout before cancelling.此外,您可以使用
CancellationTokenSource.CancelAfter(TimeSpan)
在取消之前设置超时。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.