如何使用Task.Run(Func <task> f)方法签名?

时间:2015-05-22 15:03:16

标签: c#

使用此方法:

public static Task Run(Action action)

我写道:

void MyMethod(){ //do something }
Task t = Task.Run(new Action(MyMethod));

但是我不明白如何使用以下重载

public static Task Run(Func<Task> f)

msdn提到返回的任务是&#34;任务的代理 f&#34;这让我更加困惑。代理是什么意思,我将如何调用此方法?

4 个答案:

答案 0 :(得分:5)

Func<Task>只是返回任务的函数。然后执行那个任务。

因此Task Run( Func<Task> f )会返回Task,其作用是运行另一个Task(由f创建的Run<TResult>(Func<Task<TResult>>))。 那是“代理”的含义。

但是,请阅读关于MSDN的注释(强调添加):

  

语言编制器使用async方法来支持awaitf=@(idx, varargin) subsref(cellfun(@(x) x(idx), varargin, 'uni', 0), substruct('{}', {':'})); 关键字。 不打算直接从用户代码中调用

答案 1 :(得分:1)

Func<T>是一个通用代表 - 这里有完整的签名:

public delegate TResult Func<out TResult>()

如您所见,它表示不带参数的函数,并返回类型为TResult的实例。对于Func<Task>TResultTask

这意味着,您可以这样做:

public Task MyAsyncMethod() { ... }

Task.Run(MyAsyncMethod); 

这会将您的方法MyAsyncMethod转换为Func<Task>类型的委托,并将其传递给Task.Run。它是Task.Run( new Func<Task>(MyAsyncMethod) );

的语法糖
  

msdn提到返回的任务是&#34; f&#34;返回的任务的代理。这对我来说更令人困惑(代理人的意思是什么?)

这意味着Task.Run只会将MyAsyncMethod返回的任务换成另一个Task

答案 2 :(得分:1)

当您运行Task.Run时,该签名允许您提供返回任务的方法。这是因为Func<T>的最后一个通用参数是您提供的委托给出的返回值。含义:

public Func<bool> IsValid = this.ValidateUser;
public bool ValidateUser() { return someUser.IsAuthenticated; }

甚至只是

public Func<bool> IsValidUser = this.User.IsAuthenticated;

然后您可以像使用任何其他方法一样使用委托,委托将返回一个bool。

public void Foo()
{
    if (!IsValidUser()) throw new InvalidOperationException("Invalid user");
}

您可以通过提供除返回值之外的其他泛型类型来使用传递给委托的参数。

Func<int, bool> IsUserAgeValid = (age) => return age > 18;

// Invoke the age check
bool result = this.IsUserAgeValid(17);

要记住的是,最后一个泛型始终是Func中的返回类型。如果只提供了一个泛型,那么就没有参数,只有返回类型。

Func<Task>允许您在awaitable电话中使用Task.Run方法。 这也意味着您可以从您提供的匿名代表中await

public Task Foo()
{
    /* .. do stuff */
}

public void Bar()
{
    Task.Run(async () => 
        {
            await Foo();
            /* do additional work */
        });
}

如果您不需要等待Foo()的来电,则可以Task.Run Foo方法。

Task.Run(Foo);

如果你发现自己想要等待Task.Run给出的等待方法,如上所示,你可能最好使用ContinueWith

public void Bar()
{
    Task.Run(Foo).ContinueWith(foosTaskResult => 
    {    
        /* Do stuff */
    });
}

MSDN文档说明返回的任务是 f 任务的代理,基本上意味着

Task returnedTask = Task.Run(Foo);

会将returnedTask设置为调用等待Foo()方法返回的任务。

答案 3 :(得分:0)

T是指返回Task的方法,在这种情况下是MyMethod。因此,要使Task MyMethod() {...} 与此特定重载兼容,您需要编写

MyMethod

这也意味着您可以制作asyncasync Task MyMethod() {...} 方法,因此

Task

当引用“代理”时,这意味着Task.Run返回的MyMethod实际上不是declareEvents: function () { var me = this, $el; $.each(me._$listItems, function (i, el) { $el = $(el); me._on($el, 'mouseenter', $.proxy(me.onListItemEnter, me, i, $el)); }, 返回的任务,而是包裹它。