Search code examples
taskcontinuewith

Why this weird results when playing around with task and continuewith


    Dim d = 1
    Dim task1 = Task.Delay(1)
    Dim task2 = Task.Delay(2)
    Dim task4 = Sub() d += 1 'Type of task4 is delegate sub


    Dim task3 = task1.ContinueWith(task2) ' error
    Dim task5 = task1.ContinueWith(Sub() d += 1) 'works
    Dim task6 = task1.ContinueWith(task4) 'error
    Dim task7 = task1.ContinueWith(New Action(Of Task)(task2)) 'error the "new" operator lead to         Public delegate void Action<In T>(T obj); 
    'translated to vb.net it should be Public Delegate Sub Action(Of In T)(ByVal obj As T) 
    'so no new definition. Not sure what (Of In T) means
    Dim task8 = task1.ContinueWith(New Action(Of Task)(Function() task2)) ' Somehow it works. Is this even the right way to do it? Why?

The first 4 rows are normal. I just set things up

Dim d = 1
Dim task1 = Task.Delay(1)
Dim task2 = Task.Delay(2)
Dim task4 = Sub() d += 1 'Type of task4 is delegate sub

What I really want to do is to create another task, say task3. And task3 will simply be task1, continue with task2

I try a bunch of different things and follow from some answer to some questions (I think I made the question, but I forget where) a long time ago.

Doing it

Dim task3 = task1.ContinueWith(task2) ' error

Simply doesn't work.

Doing it

Dim task5 = task1.ContinueWith(Sub() d += 1) 'works

surprisingly work. Even though Sub() d += 1 is just a lambda sub. Now I know, delegate, lambda sub, and action is kind of synonym to one another, and to what extend I have no idea.

However, Sub() d += 1 has nothing to do with Task. ContinueWith accept Action(of Task) right?

So I have no idea. Besides, doing it like that would only work for non await function.

Dim task6 = task1.ContinueWith(task4) 'error

That one doesn't work. Even though task5 and task6 should be the same and have same type.

Usually if we have dim someVar=5, we can put someVar anywhere we put 5. Same value, same type.

Here, we have

Dim task4 = Sub() d += 1

I can put

Dim task5 = task1.ContinueWith(Sub() d += 1) 'works

but not Dim task6 = task1.ContinueWith(task4) 'error

Now, ContinueWith accepts Action(of Task) so a natural thing to do is to create an Action(of Task) object

Dim task7 = task1.ContinueWith(New Action(Of Task)(task2))

Doesn't work.

Then finally someone suggested using

    Dim task8 = task1.ContinueWith(New Action(Of Task)(Function() task2)) ' Somehow it works. Is this even the right way to do it? Why?

And it compiles. However, how the hell it works?

Basically I am calling the Action(Of Task) constructor and I am passing Function() task2 as a parameter. Why?

Where is the constructor of Action(Of Task)? I go to definition and I see

public delegate void Action<in T>(T obj);

Which is translateable to

Public Delegate Sub Action(Of In T)(ByVal obj As T)

And I have no idea what that means. I thought it should look like Public Sub New Action (of T)(something)

It doesn't even have New word in it.

And I am very confused.

Can anyone explain all these phenomena?


Solution

  • Delegates represent code that can be run in the future. Tasks represent code that is already running.

    ContinueWith runs code in the future (when the task completes), so it only takes delegates as its arguments, not tasks.

    On a side note, you should not normally use ContinueWith; use Await instead.