C# 命名任务什么是正确的方法?
C# Named Tasks What's the proper way?
我正在尝试处理串联任务。
我的想法是有类似于下一个代码的东西,但是VS将我的代码标记为:
cannot convert from 'System.Threading.Tasks.Task' to 'System.Action' in 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);
}
}
这是正确的语法(下面的解释):
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
作为参数,因此您可以使用它的 return 值。
您还可以使用 Task.Factory
的 流畅语法 ,这也消除了您使用 Task.Start()
:
的需要
Task.Factory.StartNew(GetLocalDbRecords)
.ContinueWith(x => CreatePlainTextFile())
.ContinueWith(x => SendToWS())
.Wait();
要使用 CancellationToken
,您需要使用 CancellationTokenSource
,它的工作方式如下:
来自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.
还有一个代码示例:
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.
当您使用 tokenSource.Cancel();
时,Task
s 不会自动停止,因为它们可能 运行 在调用它们的同一个 Thread
上,它们必须知道 CancellationToken
并轮询 IsCancellationRequested
如果他们希望根据它停止,但是,如果 Task
或其连续的 Task
试图在 CancellationToken
时开始已经请求取消,Task
或其连续的 Task
不会首先被调用。
此外,您可以使用 CancellationTokenSource.CancelAfter(TimeSpan)
以便在取消前设置超时。
我正在尝试处理串联任务。
我的想法是有类似于下一个代码的东西,但是VS将我的代码标记为:
cannot convert from 'System.Threading.Tasks.Task' to 'System.Action' in 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);
}
}
这是正确的语法(下面的解释):
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
作为参数,因此您可以使用它的 return 值。
您还可以使用 Task.Factory
的 流畅语法 ,这也消除了您使用 Task.Start()
:
Task.Factory.StartNew(GetLocalDbRecords)
.ContinueWith(x => CreatePlainTextFile())
.ContinueWith(x => SendToWS())
.Wait();
要使用 CancellationToken
,您需要使用 CancellationTokenSource
,它的工作方式如下:
来自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.
还有一个代码示例:
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.
当您使用 tokenSource.Cancel();
时,Task
s 不会自动停止,因为它们可能 运行 在调用它们的同一个 Thread
上,它们必须知道 CancellationToken
并轮询 IsCancellationRequested
如果他们希望根据它停止,但是,如果 Task
或其连续的 Task
试图在 CancellationToken
时开始已经请求取消,Task
或其连续的 Task
不会首先被调用。
此外,您可以使用 CancellationTokenSource.CancelAfter(TimeSpan)
以便在取消前设置超时。