Steve
Steve

Reputation: 4503

What's the difference with ContinueWith and without?

I run these two versions and it seems like each is giving me the same output, which is sequential.

ContinueWith_Method1a();
ContinueWith_Method1b();

and

Task.Run(() => ContinueWith_Method1a())
        .ContinueWith(task => ContinueWith_Method1b())
        .Wait();

I tried with the below but get this error:

Cannot implicitly convert type 'void' to 'System.Threading.Tasks.Task'

Task t = Task.Run(() => ContinueWith_Method1a())
        .ContinueWith(task => ContinueWith_Method1b())
        .Wait();

static void ContinueWith_Method1a()
{
    System.Console.WriteLine("Continue With Method 1a started.");
    Thread.Sleep(1000);// Simulate task processing time.

    System.Console.WriteLine("Continue With Method 1a completed.");
}

static void ContinueWith_Method1b()
{
    System.Console.WriteLine("Continue With Method 1b started.");
    Thread.Sleep(1000);// Simulate task processing time.

    System.Console.WriteLine("Continue With Method 1b completed.");
}

Upvotes: 0

Views: 90

Answers (2)

Peter Duniho
Peter Duniho

Reputation: 70671

What's the difference with ContinueWith and without?

The title question of your post is very misleading. The use of ContinueWith() in your code examples is the least interesting difference. The much more significant difference is that the first example just calls the methods directly, while the second uses Task.Run().

Now, as it happens there would be no reason to write the code as in your second example. Even ignoring the ContinueWith() aspect, if all your task does is call a method, and all you're going to do with the task is synchronously wait on the task (i.e. call the Wait() method), then you might as well just call that method in your current thread. No need for Task.Run() in that situation.

Similarly, if all you're going to do with ContinueWith() is call another method immediately after, you might as well just call the method directly.

By blocking in the current thread, you've rendered useless any advantage there might have been in executing those two methods asynchronously.

Of course, there is a clear mechanical difference. You get the same results, ultimately, but how that result is achieved is very different. In the first example, you just call the methods, one after another. Each call executes in the current thread. In the second example, you are essentially asking the thread pool to execute each method in sequence, while you block the current thread waiting for that to happen.

It's similar to the difference between you peeling an onion and then chopping it yourself, and asking someone else to peel an onion and then chop it while you sit around twiddling your thumbs waiting for them to finish those actions.

Finally, as far as the error message you got, "Cannot implicitly convert type 'void' to 'System.Threading.Tasks.Task'", that only happened because you added the Task t variable and tried to set it to the result of the Wait() method. Since the Wait() method doesn't return anything (i.e. has a declared return type of void), never mind a value of Task, it's not possible to set the value of t using its return value. Hence the error message. If you want to assign a Task variable, you would need to just leave out the call to Wait():

Task t = Task.Run(() => ContinueWith_Method1a())
        .ContinueWith(task => ContinueWith_Method1b());

Upvotes: 1

OwnBlood
OwnBlood

Reputation: 197

ContinueWith starts the next Task after the first finished. So both your examples run synchroniously ( first methode A then methode b)

EDIT:

As an addition to your edit, your error is caused by the .Wait() function, which awaits the Task and returns void.

Upvotes: 2

Related Questions