简体   繁体   English

C# 命名任务的正确方法是什么?

[英]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.

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