w0051977
w0051977

Reputation: 15807

Variable contained in Lambda expression not defined

Please see the code excerpt below, which I found here: https://msdn.microsoft.com/en-us/library/dd537612(v=vs.110).aspx:

static void SimpleContinuation()
      {
         string path = @"C:\users\public\TPLTestFolder\";
         try
         {
            var firstTask = new Task(() => CopyDataIntoTempFolder(path));
            var secondTask = firstTask.ContinueWith((t) => CreateSummaryFile(path));
            firstTask.Start();
         }
         catch (AggregateException e)
         {
            Console.WriteLine(e.Message);
         }
      }

I am confused by the Lambda expression:

var secondTask = firstTask.ContinueWith((t) => CreateSummaryFile(path));

What is the purpose of: (t)? and why is it contained in brackets? t is not defined anywhere.

I have read this webpage, however it has not answered my question: https://msdn.microsoft.com/en-us/library/bb397687.aspx

Upvotes: 0

Views: 201

Answers (3)

ispiro
ispiro

Reputation: 27673

Task.ContinueWith needs an Action<Task> - a "method" that accepts a Task as its argument. t will be the Task argument that ContinueWith will supply that method with.

That method being something like:

void noName(Task t)
{
    CreateSummaryFile(path);
}

ContinueWith will then execute this anonymous method at the appropriate time supplying it with t (which will be ignored), and calling CreateSummaryFile(path).

Upvotes: 1

Jon Hanna
Jon Hanna

Reputation: 113262

It would perhaps be a bit clearer if you realise that the form used there is a shorthand and the full form is:

(Task t) => CreateSummaryFile(path)

It defines an Action<Task> and so the counter to t is not defined anywhere is that it is in fact defined there.

You're allowed to leave out the type when it can be inferred from context (as it is here). You're also allowed to leave out the parentheses when there is exactly one parameter, so this could also be:

t => CreateSummaryFile(path)

Now, t isn't used here, but it often is and that can be very useful. More so when ContinueWith is called on a Task<TResult> as then the type of t would be Task<TResult> and the result could be used in the subsequent task.

Some people like to use _ for parameters that aren't used to signal "I have to put a parameter here, but it's not doing anything. But then some people hate that convention too. YMMV.

Upvotes: 1

Sefe
Sefe

Reputation: 14007

The signature of ContinueWith is:

Task ContinueWith(Action<Task> continuationAction)

The Action<Task> part means that you have to pass a delegate with one input parameter of type Task and a return of void. That is, ContinueWith will call that delegate at an appropriate time and pass an argument of type Task.

A lamdba expression in C# is a shorthand for a delegate. To the left of the lambda operator ( => ) are the parameters, to the right the body that will be executed. Since you will get an argument of type Task, you will need a parameter of that type. In your case that is t. That you don't need this value makes no difference. You still need to declare it to satisfy the lamdba expression's signature.

Upvotes: 0

Related Questions