2

In the following code:

async static Task<int> test(){ 
    Console.WriteLine("{0}: Start 3", DateTime.Now);
    await Task.Delay(3000);
    return 3; 
}

List<Task<int>> tasks2 = new List<Task<int>> {
    test(),
    new Task<int>( delegate { Console.WriteLine("{0}: Start 3", DateTime.Now); Task.Delay(3000).Wait(); return 3; } ),
    new Task<int>( delegate { Console.WriteLine("{0}: Start 1", DateTime.Now); Task.Delay(1000).Wait(); return 1; } ),
};


foreach (var task in tasks2)
    task.Start(); // this cause exception at runtime

Why I can't use test method as Task<int>? If function returns Task<int>...

0

3 Answers 3

3

The task returned by test() has already started when you invoked test(). So you cannot start it again.

Actually, the task returned by test() is a promise-style task that does not run on the thread-pool thread in the first place.

You should almost always create tasks that have already started (once they are created).

I.e., you should not use the constructor of Task and then call the Start method.

Instead, if you want to run the task on a thread-pool thread, use Task.Run.

Sign up to request clarification or add additional context in comments.

4 Comments

"You should almost always create tasks that have already started (once they are created)." - Why? What if I want to run them latter?
" the task returned by test() is a promise-style task" - What is this?
Because Task.Run is a better alternative. Take a look at this article. If you want to create something and start it later, use Action<T>, and then start it via Task.Run later.
Here is a good article about promise tasks.
0

As others mentioned you cannot call Start as it was already started. You could still achieve your goals by checking for the status, if that is what you wish for. Please see the updated code below:

async static Task<int> test(){ 
    Console.WriteLine("{0}: Start 3", DateTime.Now);
    await Task.Delay(3000);
    return 3; 
}


        List<Task<int>> tasks2 = new List<Task<int>> {
           new Task<int>( delegate{ return test().Result;}),
            new Task<int>( delegate { Console.WriteLine("{0}: Start 3", DateTime.Now); Task.Delay(3000).Wait(); return 3; } ),
            new Task<int>( delegate { Console.WriteLine("{0}: Start 1", DateTime.Now); Task.Delay(1000).Wait(); return 1; } ),
            };

foreach (var task in tasks2)
{
        task.Start();
}

2 Comments

I agree, it already started. Is there a way, to pass test function as Task<int> to the List<Task<int>> ?
I have updated the List initialization part. You could now call Start when you require.
0

Like everyone else has pointed out, the task has been set in motion when you called test() so you can't start on it again. Give below code a shot to see what's going on.

As you can see, the console output comes for each of the task. Task returned by test() is started by calling that method. So, this code only explicitly starts the other tasks that are in Created status. Finally, we wait for all tasks to complete by calling WhenAll() which in turn returns a task on which we wait. You will notice the longest delay of 3 seconds (of all tasks) before "All done!" is printed.

public static class AsyncTest
{
    static async Task<int> test()
    {
        Console.WriteLine("{0}: Start 3", DateTime.Now);
        await Task.Delay(3000);
        return 3;
    }

    public static void Main()
    {

        var tasks2 = new List<Task<int>>
        {
            test(),
            new Task<int>( delegate { Console.WriteLine("{0}: Start 3", DateTime.Now); Task.Delay(3000).Wait(); return 3; } ),
            new Task<int>( delegate { Console.WriteLine("{0}: Start 1", DateTime.Now); Task.Delay(1000).Wait(); return 1; } )
        };

        foreach (var task in tasks2)
        {
            if (task.Status == TaskStatus.Created)
                task.Start();
        }

        Task.WhenAll(tasks2).Wait();

        Console.WriteLine("All done!");
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.