我正在努力处理连锁任务。
我的想法是使用与下一个代码类似的东西,但VS将我的代码标记为:
无法转换为System.Threading.Tasks.Task'到' System.Action'在Argument1
这种语法的正确方法是什么?
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();
}
我通过使用下一个代码获得了我想要的结果(我知道我必须优化它),但我的想法是通过使用" 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);
}
}
答案 0 :(得分:2)
这是正确的语法(下面的解释):
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();
请注意,ContinueWith
方法收到Task
时未收到Action<Task>
,在第一个Action
完成后会调用此Task
将收到第一个Task
作为参数,以便您可以使用它的返回值。
您还可以使用Task.Factory
的流畅语法,这也消除了您使用Task.Start()
的需要:
Task.Factory.StartNew(GetLocalDbRecords)
.ContinueWith(x => CreatePlainTextFile())
.ContinueWith(x => SendToWS())
.Wait();
要使用CancellationToken
,您需要使用CancellationTokenSource
,它的工作原理如下:
来自MSDN's Page about Task
cancellation
1)创建并启动可取消的任务。
2)将取消令牌传递给您的用户委托,并可选择传递给任务实例。
3)注意并回复您的用户代表中的取消请求。
4)可选地在调用线程上注意任务被取消。
代码示例:
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
时, tokenSource.Cancel();
不会自动停止,因为它们可能会在调用它们的同一Thread
上运行,并且必须知道CancellationToken
和民意调查IsCancellationRequested
如果他们希望根据它停止,但是,如果Task
或其连续的Task
试图在CancellationToken
已被请求取消时尝试启动, <{1}}或其连续的Task
首先不会被调用。
此外,您可以使用Task
在取消前设置超时。