用于传递异步委托的方法签名是什么?

问题描述 投票:55回答:3

我最近从Objective-C领域回到了C#,C#5中的async / await关键字看起来很酷。但是我仍在尝试使用正确的语法。

我想声明一个将异步委托作为参数的方法,但是我在使调用方和被调用方语法正确的过程中遇到麻烦。有人可以提供代码示例来显示方法声明,调用和对委托的调用吗?

我认为该声明将类似于以下内容。请注意,该函数不是异步的。即它的异步性与委托无关。

void DoSomethingWithCallback(async delegate foo(int)) 
{
    ...
    foo(42);
    ...
}

该呼叫将类似于:

DoSomethingWithCallback(async (int x) => { this.SomeProperty = await SomeAsync(x); });

当然,这些都不会编译,并且我见过的大多数示例都假定一个字段或属性是委托,而不是我要使用的匿名委托。

c# asynchronous delegates
3个回答
71
投票

将委托作为参数的函数必须使用命名委托类型;与Objective-C不同,您不能在函数定义中内联声明匿名委托类型。但是,提供了泛型Action <>和Func <>,因此您不必自己声明新类型。在下面的代码中,我假设委托将单个int作为参数。

void DoSomethingWithCallback(Func<int,Task> callbackDelegate)
{
    Task t = callbackDelegate(42);
}

如果此函数不实际上对返回的Task对象执行任何操作(如上面的代码所示),则可以使用Action<int>作为委托类型。如果使用Action,您仍然可以声明委托异步(如下),但是返回的隐式Task对象将被忽略。

用于调用上述函数的lambda语法很简单,并且您在问题中使用的语法是正确的。请注意,此处不需要指定参数类型,因为可以推断出它:

DoSomethingWithCallback(async (intParam) => { this.myint = await Int2IntAsync(intParam); });

如果愿意,您也可以传递方法或委托变量,而不是使用lambda语法:

async Task MyInt2Int(int p) { ... }
Func<int,Task> myDelegate;
void OtherMethod()
{
    myDelegate = MyInt2Int;
    DoSomethingWithCallback(myDelegate); // this ...
    DoSomethingWithCallback(MyInt2Int);  // ... or this.
}

8
投票

如果没有返回类型,则方法签名的返回类型为Task,如果有返回类型,则为Task<T>

Tho,我不确定100%是否可以拥有这样的异步lambda。

在使用任务的方法中,您将'等待'任务或使用Task上的属性和方法来获得结果。


0
投票

如果我有一个要传递但不执行的任务,则可以将该任务包装在Func<>中,然后调用该Func<>创建该任务。 await可以按常规方式使用。

public class Example {
    public Example(Func<Task> toBeExecutedInTheFuture)
    {
        FutureTask = toBeExecutedInTheFuture;
    }

    public async void ExecuteTaskExample()
    {
        await FutureTask();

        // or alternatively

        var myTask = Task.Run(FutureTask());
        // do work
        await myTask;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.