c# .net why does Task.Run seem to handle Func differently than other code?

前端 未结 6 1478
生来不讨喜
生来不讨喜 2021-01-01 16:07

The new Task.Run static method that\'s part of .NET 4.5 doesn\'t seem to behave as one might expect.

For example:

Task t = Task.Run(()=&         


        
6条回答
  •  悲哀的现实
    2021-01-01 16:25

    When you pass a Func into a method Run(Func) you don't have to specify the generic on the methodcall because it can infer it. Your lambda does that inference.

    However, your function is not actually a Func whereas the lambda was.

    If you do Func f = MyIntReturningMethod it works. Now if you specify Task.Run(MyIntReturningMethod) you would expect it to work also. However it can't decide if it should resolve the Func> overload or the Func overload, and that doesn't make much sense because its obvious that the method is not returning a task.

    If you compile something simple like follows:

    void Main()
    {
        Thing(MyIntReturningMethod);
    }
    
    
    public void Thing(Func o)
    {
        o();
    }
    
    public Int32 MyIntReturningMethod()
    {
    return (5);
    }
    

    the IL looks like this....

    IL_0001:  ldarg.0     
    IL_0002:  ldarg.0     
    IL_0003:  ldftn       UserQuery.MyIntReturningMethod
    IL_0009:  newobj      System.Func..ctor
    IL_000E:  call        UserQuery.Thing
    

    (Some of the extra stuff is from LINQ Pad's additions... like the UserQuery part)

    The IL looks identical as if you do an explicit cast. So it seems like the compiler does't actually know which method to use. So it doesn't know what cast to create automatically.

    You can just use Task.Run((Func)MyIntReturningMethod) to help it out a bit. Though I do agree that this seems like something the compiler should be able to handle. Because Func> is not the same as Func, so it doesn't make sense that they would confuse the compiler.

提交回复
热议问题