Task.ContinueWith不调用第二个任务(只有第一个任务正在运行)

时间:2014-11-11 09:26:21

标签: c# .net multithreading asynchronous

我的应用程序允许用户创建"任务"来自UI的对象并设置它们的执行顺序。从那里,当用户点击"运行"所有任务(按顺序)都被发送到一个类,该类假设链接并运行它们。课程如下:

public class MaintenanceTask
{
    private CancellationTokenSource m_CancellationTokenSource;
    private Task m_BatchTask;

    public MaintenanceTask()
    {            
        m_CancellationTokenSource = new CancellationTokenSource();            
    }

    public void AddTaskIdent(TaskIdentBase ident)
    {
        Task newTask = ident.Create(m_CancellationTokenSource.Token);

        if (m_BatchTask == null)
            m_BatchTask = newTask;            
        else                
            m_BatchTask.ContinueWith(prev=>newTask);                        
    }

    public void Run()
    {
        if (m_BatchTask != null)
            m_BatchTask.Start();
    }
}

AddTaskIdent正在接收一个知道如何创建Task对象的基类。 我的问题是调用Run()启动发送给类的第一个任务。它运行它直到完成后才能运行其他任务。 它在第一个任务完成后就停止了。

我是否遗漏了使用ContinueWith机制的内容?

5 个答案:

答案 0 :(得分:1)

注意“foo.ContinueWith(completedTask => otherTask);”没有启动otherTask。 你需要像“foo.ContinueWith(completedTask => otherTask.Start());”

在调试器中尝试此操作,这可能会帮助您了解其工作原理:

        static void Main(string[] args)
        {
            Task task1 = new Task(() => Console.WriteLine("1"));
            Task task2 = new Task(() => Console.WriteLine("2"));
            Task task3 = new Task(() => Console.WriteLine("3"));

            task1.ContinueWith(previous => task2.Start());
            task2.ContinueWith(previous => task3.Start());

            task1.Start();
            task2.Wait();
            Console.WriteLine("Done.");
        }

答案 1 :(得分:1)

问题出在这一行:

m_BatchTask.ContinueWith(prev=>newTask);

我认为newTaskident.Create返回时未启动if (m_BatchTask != null) { m_BatchTask = newTask; //you'd like to have the m_lastTask field because next chaining operation //should be on the last task, not the one you are starting m_lastTask = newTask; } else { m_lastTask.ContinueWith( prev => { newTask.Start(); //doesn't matter to return newTask because in that case //on second chaining already you will get Task<Task> return (object)null; }); m_lastTask = newTask; } 。 所以你应该:

{{1}}

答案 2 :(得分:1)

最后在合并所有答案的数据并继续使用Google搜索后将其投入使用。 工人阶级是:

public class MaintenanceTask
{
    private CancellationTokenSource m_CancellationTokenSource;
    private Task m_FirstTask;
    private Task m_LastTask;

    public MaintenanceTask()
    {
        m_CancellationTokenSource = new CancellationTokenSource();
    }

    public void AddTaskIdent(TaskIdentBase ident)
    {
        Task newTask = ident.Create(m_CancellationTokenSource.Token);

        if (m_FirstTask == null)
        {
            m_FirstTask = newTask;
            m_LastTask = m_FirstTask;
        }
        else
        {                
            m_LastTask.ContinueWith(prev => newTask.Start());
            m_LastTask = newTask;
        }
    }

    public void Run()
    {
        if (m_FirstTask != null)
            m_FirstTask.Start();
    }
}

答案 3 :(得分:0)

你有没有用

检查了else分支
  else                
        m_BatchTask.ContinueWith(prev=>newTask);       

被称为?

正如我所看到的,当m_Batch任务向其应用下一个任务时,该任务最初为null,但是没有提升继续

答案 4 :(得分:0)

说实话,我认为你错误地使用Task。在大多数情况下,Task代表已经发生的工作。

这就是我要编写你想要的代码&#34;假设C#5。

public void AddToQueue(Action action)
{
    if (m_BatchTask == null)
        m_BatchTask = Task.Run(action);            
    else                
        m_BatchTask = AddToQueue(m_BatchTask, action);                        
}

public async Task AddToQueue(Task existingTask, Action action)
{
    await existingTask;
    action();                       
}