Reputation: 3585
The following works :
public static void Main( string[] args ){
Task FooTask = Task.Run( ( ) => Console.WriteLine( "Bar" )
).ContinueWith( T => Console.WriteLine( "Baz" ) );
FooTask.Wait( );
Console.WriteLine( "Press Enter To Exit." );
Console.ReadLine( );
}
The following does not - ( Bar is printed, Baz is not ).
static void printFirstMessage( ){
console.WriteLine( "Bar" );
}
static void printFirstMessage( ){
Console.WriteLine( "Baz" );
}
public static void Main( string[] args ){
//I say "new Action( ... )" because if I don't, I get an IDE error
//that says "The call is ambiguous between..."
Task FooTask = Task.Run( new Action( printFirstMessage )
).ContinueWith( new Action( printSecondMessage ) );
Console.WriteLine( "Press Enter To Exit." );
Console.ReadLine( );
}
This is an oversimplification of my real issue where I would like to be able to chain two methods together into a task, then do some other stuff, then Wait( )
out the task before exiting the method.
Why does the first instance work fine, but the second instance fail?
Upvotes: 0
Views: 235
Reputation: 456407
Yet Another Stupid Task.ContinueWith Issue
You shouldn't be using ContinueWith
. It's a low-level, inherently dangerous API with several non-obvious pitfalls.
Why does the first instance work fine, but the second instance fail?
As Servy answered, it's because ContinueWith
doesn't take an Action
parameter - it takes Action<Task>
. However, this is really the wrong question...
This is an oversimplification of my real issue where I would like to be able to chain two methods together into a task, then do some other stuff, then Wait( ) out the task before exiting the method.
The proper way to chain is to use await
:
private static async Task DoBothAsync()
{
await Task.Run(() => Console.WriteLine("Bar"));
Console.WriteLine("Baz");
}
public static void Main(string[] args)
{
Task FooTask = DoBothAsync();
FooTask.Wait();
Console.WriteLine("Press Enter To Exit.");
Console.ReadLine();
}
Also, I find the use of Task.Run
questionable. It's probably not necessary.
Upvotes: 1
Reputation: 350
Task.Run() returns an awaitable Task, which you on which you call ContinueWith. ContinueWith also returns an awaitable Task, which is why you'll need to return something from your ContinueWith call. Try this, which will let you wait for the second task (t) (the printSecondMessage action):
Task FooTask = Task.Run(() => printFirstMessage())
.ContinueWith(t => printSecondMessage());
FooTask.Wait();
Upvotes: 0
Reputation: 203814
ContinueWith
doesn't accept an Action
as the first parameter. There are in fact quite a lot of different overloads, but all of them accept a delegate that takes a Task
, along with potentially other parameters, and different overloads of ContinueWith
have additional parameters besides just a delegate.
If you used Action<Task>
instead of Action
(and provided a method with the appropriate signature) then the code would compile, as your first example does.
Upvotes: 3
Reputation: 5303
The syntax you have specified in your second example is incorrect and does not even compile. If you correct the syntax to what I think you are meaning (see below) then the code works the same as the first example:
static void printFirstMessage()
{
Console.WriteLine("Bar");
}
static void printSecondMessage()
{
Console.WriteLine("Baz");
}
public static void Main(string[] args)
{
Task FooTask = Task.Run(() => printFirstMessage())
.ContinueWith(t => printSecondMessage());
Console.WriteLine("Press Enter To Exit.");
Console.ReadLine();
}
Upvotes: 0