Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any way to start task using ContinueWith task?

Tags:

My code:

var r = from x in new Task<int>(() => 1)         from y in new Task<int>(() => x + 1)          select y; r.ContinueWith(x => Console.WriteLine(x.Result)).Start();    

or

new Task<int>(() => 1)     .ContinueWith(x => x.Result + 1)     .ContinueWith(x => Console.WriteLine(x.Result))     .Start(); 

Exception:

Start may not be called on a continuation task.

So I need to start the first task. Is there any way to call last task Start method to run all tasks?

like image 739
dotneter Avatar asked Dec 10 '10 13:12

dotneter


People also ask

What does calling task ContinueWith () do?

ContinueWith(Action<Task>)Creates a continuation that executes asynchronously when the target Task completes.

What is Task continuation?

A continuation task (also known just as a continuation) is an asynchronous task that's invoked by another task, known as the antecedent, when the antecedent finishes.

How do I start a task in C#?

To start a task in C#, follow any of the below given ways. Use a delegate to start a task. Task t = new Task(delegate { PrintMessage(); }); t. Start();

Which code creates a chain of task to be executed after one another?

c# - Run sequence of tasks, one after the other - Stack Overflow. Stack Overflow for Teams – Start collaborating and sharing organizational knowledge.


2 Answers

Any reason not to use Task.Factory.StartNewmsdn, ms docs for the first task? Yes, it's inconsistent - but it's fundamentally a different kind of task, in terms of being started explicitly rather than just as a continuation.

like image 102
Jon Skeet Avatar answered Oct 05 '22 12:10

Jon Skeet


I'm not really sure what's wrong with just writing this:

var t1 = new Task<int>(() => 1) var r = from x in t1         from y in new Task<int>(() => x + 1)          select y; r.ContinueWith(x => Console.WriteLine(x.Result)); t1.Start(); 

or this:

var t = new Task<int>(() => 1) t.ContinueWith(x => x.Result + 1)  .ContinueWith(x => Console.WriteLine(x.Result)) t.Start(); 

That directly expresses what you actually want to do. (It's the initial task that you want to kick off. So what's wrong with invoking Start on that initial task?) Why are you looking for a syntax that obscures that?

EDIT: fixed first example...

EDIT 2 to add:

So I realise now that LinqToTasks expects task selectors to return running tasks. So the second from clause in your first example returns a task that nothing will ever run. So what you actually need is this:

var t1 = new Task<int>(() => 1); var r = from x in t1         from y in Task<int>.Factory.StartNew(() => x + 1)         select y; r.ContinueWith(x => Console.WriteLine(x.Result)); t1.Start(); 

Nothing else is going to call Start on the tasks produced in these from clauses. Since the relevant selectors don't actually get executed until the previous task completes, you're still in control of when to kick off the root task.

That appears to work, but it's pretty ugly. But that appears to be how LinqToTasks is designed... I think I'd stick with the regular function call syntax.

like image 26
Ian Griffiths Avatar answered Oct 05 '22 13:10

Ian Griffiths