首页 > 解决方案 > 静止运行时任务状态更改为 RanToCompletion

问题描述

我创建了一个方法,它在启动作为参数传递的任务之前处理一些检查。

我的问题是,在那里创建的任务没有按预期运行,尽管代码仍在运行,但很快就会被视为 RanToCompletion。

这是一个例子:

    public Task Main(CancellationToken localToken)
    {
        try
        {
            AddToTasker(new Task(async () => await ExtractAllOffer(localToken), localToken), TaskTypes.Extractor);

            //this allows to extract only the task for the given task type through the list created in AddToTasker, actual code is not necessary the returned array is correct
            Task.WaitAll(GetTasksArray(new TaskTypes[]{TaskTypes.Extractor}), localToken);

            IsRunning = false;
        }
    }

    public void AddToTasker(Task task, TaskTypes taskstype)
    {

        /*
         * Whatever code to perform few check before starting the task
         * among which referencing the task within a list which holds also the taskstype
         */


        task.Start();

    }

    async private Task ExtractAllOffer(CancellationToken localToken)
    {
        // *** Do very long Stuff ***
    }

ExtractAllOffer 方法是一个循环,有一段时间我在await外部代码完成。首先await终止Task.WaiAll并转到IsRunning = false

我检查了这个线程,但它似乎与我正确使用异步任务而不是异步无效的问题不同。

此外,在我在 AddToTasker 方法中转移任务执行之前,代码可以正常运行。在我以前这样做之前,AddToTasker(Task.Run(() => ExtractAllOffer(localToken), localToken), TaskTypes.Extractor);但我意识到我需要在启动任务之前执行检查,并且需要在 AddToTasker 方法中考虑检查(我有很多调用这个方法)。

我有点理解我声明或启动任务的方式存在缺陷,但不知道是什么。

非常感谢帮助

标签: task-parallel-library

解决方案


感谢@pere57 和这个其他线程,我看到等待只等到创建任务的操作完成......这非常快。

我必须将其声明为 Task<Task> 以便解开第一个任务(操作)以访问内部任务(实际执行的方法)。

所以这里是:

public Task Main(CancellationToken localToken)
{
    try
    {
        AddToTasker(new Task<Task>(() => ExtractAllOffer(localToken), localToken), TaskTypes.Extractor);

        //this allows to extract only the task for the given task type through the list created in AddToTasker, actual code is not necessary the returned array is correct
        Task.WaitAll(GetTasksArray(new TaskTypes[]{TaskTypes.Extractor}), localToken);

        IsRunning = false;
    }
}

public void AddToTasker(Task<Task> task, TaskTypes taskstype)
{

    /*
     * Whatever code to perform few check before starting the task
     * among which referencing the task within a list which holds also the taskstype
     */

    mylistoftask.Add(task.Unwrap()); //I have now to unwrap the task to add the inner one in my list
    task.Start();

}

async private Task ExtractAllOffer(CancellationToken localToken)
{
    // *** Do very long Stuff ***
}

推荐阅读