2

I accidentally bumped into an issue, that I was able to resolve. However, I am a worried about my inability to understand why the error-ed code was able to compile (at first place).

Following is the error-ed code, that compiles fine:

Task<string> myTask = Task<string>.Factory.StartNew(() =>
            {
                System.Threading.Thread.Sleep(1000);
                return "mystrineg";
            });
            myTask.ContinueWith(t => action, CancellationToken.None,
                TaskContinuationOptions.NotOnFaulted, TaskScheduler.Default);

The issue with the above code is : action won't get called at all. Here is the fix I made:

Task<string> myTask = Task<string>.Factory.StartNew(() =>
            {
                System.Threading.Thread.Sleep(1000);
                return "mystrineg";
            });
            myTask.ContinueWith(t => action(t.Result), CancellationToken.None,
                TaskContinuationOptions.NotOnFaulted, TaskScheduler.Default);

My question is, why is the compiler allowing to call a parametrized action without an argument?

nvoigt
  • 75,013
  • 26
  • 93
  • 142
James
  • 1,213
  • 2
  • 15
  • 26
  • All the answers are right. However, I had to choose the one that arrived early and was clear. Thank you all! – James Oct 17 '16 at 12:35

3 Answers3

3

Your first code will use this overload, and what it will do is to return the action delegate and will not execute it at all.

The overload you actually need is this and your second code actually uses it and will execute your action.

I am wondering why didn't you use async and await instead of ContinueWith and Task.Run instead of Task.Factory.StartNew which can be dangerous.

Your code can be much simpler:

Task<string> myTask = Task.Run(() =>
                      {
                          System.Threading.Thread.Sleep(1000);
                          return "mystrineg";
                      });
string str = await myTask;
action(str);
Community
  • 1
  • 1
YuvShap
  • 3,825
  • 2
  • 10
  • 24
2

My question is, why is the compiler allowing to call a parametrized action without an argument?

It does not. In your first version, you did not call action at all. Not even with no arguments. You would have needed to pass it directly without the lambda or call it with an empty pair of () to actually call it.

While action; would not be a valid statement, .ContinueWith will not only take an Action<Task>, but also a Func<Task, T> and that is exactly what you passed... a function taking a Task, returning whatever Type your action has: t => action;

nvoigt
  • 75,013
  • 26
  • 93
  • 142
2
t => action

is a short for:

t => { return action; }

hence the result.

Maku
  • 1,464
  • 11
  • 20