代码之家  ›  专栏  ›  技术社区  ›  JasonC

除了使用lambda函数,还有其他方法可以将参数输入到任务中吗?

  •  1
  • JasonC  · 技术社区  · 3 年前

    除了使用lambda函数外,是否还有其他方法将参数输入到任务中?

    好像 Task.Run(DoSomethingElse(myInput)); 从那以后就应该工作了 Task.Run(DoSomething); 有效,但显然不行。

    仅使用lambda函数将带参数的函数转换为不带参数的函数似乎有些奇怪,就像一个笨拙的转换。 Task.Run(() => DoSomethingElse(myInput));

    Main()
    {
        object myInput = new();
    
        Task.Run(DoSomething); // Happy Code
        Task.Run(() => DoSomethingElse(myInput)); // Happy Code 
        Task.Run(DoSomethingElse(myInput)); // CS1503 Argument 1: cannot convert from 'System.Threading.Tasks.Task' to 'SystemAction'
    }
    
    Task DoSomething()
    {
        // Something
    }
    
    Task DoSomethingElse(object input)
    {
        // Something else
    }
    
    1 回复  |  直到 3 年前
        1
  •  1
  •   Woody1193 Nimmi Rashinika    3 年前

    查看文档 Task.Run ,你会注意到每一个定义 Func<Task> 或者 Func<Result> 或者其中的一些组合。然而,这些定义都没有提到参数。另外,你打电话时要发送的内容 Task.Run(DoSomethingElse(myInput)) 这是打电话的结果 DoSomethingElse(myInput) 因为这表示对方法本身的调用,而不是将方法及其参数作为参数发送。实际上,这就是使用Lambda所做的。如果确实不想在代码中插入lambda,可以尝试添加如下静态方法:

    public static Task Run<TItem>(f Func<TItem, Task>, i TItem) {
         return Task.Run(() => f(i));
    }
    
        2
  •  0
  •   Theodor Zoulias    3 年前

    这个 Task.Run 方法基本上是 Task.Factory.StartNew 方法,并带有一些默认参数。Stephen Toub在本文中对此进行了解释: Task.Run vs Task.Factory.StartNew .

    这个 任务工厂StartNew 还有一个超负荷的 object state 参数你可以将这个重载用于你自己的 任务跑 -比如捷径。 您将需要其中四种,以涵盖所有情况,包括有无结果以及有无异步委托:

    static Task Run(Action<object> action, object state)
    {
        return Task.Factory.StartNew(action, state, default,
            TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
    }
    static Task Run(Func<object, Task> action, object state)
    {
        return Task.Factory.StartNew(action, state, default,
            TaskCreationOptions.DenyChildAttach, TaskScheduler.Default).Unwrap();
    }
    static Task<TResult> Run<TResult>(Func<object, TResult> action, object state)
    {
        return Task.Factory.StartNew(action, state, default,
            TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
    }
    static Task<TResult> Run<TResult>(Func<object, Task<TResult>> action, object state)
    {
        return Task.Factory.StartNew(action, state, default,
            TaskCreationOptions.DenyChildAttach, TaskScheduler.Default).Unwrap();
    }
    

    用法示例:

    Task task = Run(DoSomethingElse, myInput);
    

    这种方法的优点是 myInput 不是 captured in a closure ,就像使用lambda时一样,因此程序在堆中分配的内存更少。这是一个影响很小的优化,在大多数情况下可以忽略不计。