user1108948
user1108948

Reputation:

Start a task without the use of Task.Run or TaskFactory.StartNew

Let's see:

Task.Run Method (Action): Queues the specified work to run on the ThreadPool and returns a task handle for that work.

And

TaskFactory.StartNew Method (Action): Creates and starts a task.

But my code doesn't have either of them. It can still be started and run. Why?

static void Main(string[] args)
{
    Task t = AsynchronyWithTPL();
    t.Wait();
}

static Task AsynchronyWithTPL()
{
    Task<string> t = GetInfoAsync("Task 1");
    Task t2 = t.ContinueWith(task => Console.WriteLine(t.Result), TaskContinuationOptions.NotOnFaulted);
    Task t3 = t.ContinueWith(task => Console.WriteLine(t.Exception.InnerException), TaskContinuationOptions.NotOnFaulted);
    return Task.WhenAny(t2, t3);
}

It seems Task.Wait method starts the task, but is it a good practice?

Upvotes: 0

Views: 1006

Answers (1)

i3arnon
i3arnon

Reputation: 116518

First of all. Task.Wait doesn't start a task, it waits for a task to complete.

You can start a new task by using Task.Run, Task.Factory.StartNew, new Task(...).Start() or by calling an async task (which I assume GetInfoAsync is).

An async method returns a "hot" task that was started before that method call returned. In your case you add continuations (t2, t3) to that task and then create a continuation on top of the two with Task.WhenAny.

If you're dealing with async tasks you don't need to start the tasks (and you didn't). If you want to offload work to the ThreadPool use Task.Run. Don't use Task.Factory.StartNew or new Task(...).Start() unless you must (which should be very rare).


I'm guessing (and I could be wrong) that what you meant to write is this:

static async Task AsynchronyWithTPL()
{
    try
    {
        Console.WriteLine(await GetInfoAsync("Task 1"));    
    }
    catch (AggregateException exception)
    {
        Console.WriteLine(exception.InnerException);
    }
}

Upvotes: 2

Related Questions