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

我最近从 Objective-C 的角度回到了 C # ,C # 5中的异步/等待关键字看起来很酷。但我还在尝试掌握正确的语法。

我想声明一个以异步委托作为参数的方法,但我在调用方和被调用方语法正确性方面遇到了麻烦。有人能提供一个显示方法声明、调用和对委托的调用的代码示例吗?

我觉得宣言应该是这样的。注意,这个函数不是异步的; 也就是说,它的异步性与委托无关。

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

电话应该是这样的:

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

当然,这些代码都没有编译,而且我看到的大多数示例都假定有一个字段或属性是委托,而不是我希望使用的匿名委托。

71613 次浏览

方法签名的返回类型是 Task(如果没有返回类型) ,或者是 Task<T>(如果有返回类型)。

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

在使用任务的方法中,您可以“等待”任务,或者使用 Task 上的属性和方法来获得结果。

将委托作为参数的函数必须使用命名委托类型; 与 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.
}

如果我有一个想要传递但是没有执行的任务,我可以将任务包装在一个 Func<>中,然后调用该 Func<>来创建该任务。await可以正常使用。

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


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


// or alternatively


var myTask = FutureTask();
// do work
await myTask;
}
}

请看一下这个例子,带有 Task 和一个附加参数。 我希望这能帮助人们理解如何实现它..。

// ... more code ...


// Let's call a function with a Task<T> parameter (LocalFunc)
await CustomFunctionAsync(
param1,
LocalFunc
);


// ... more code ...

已宣布的职能:

public static async Task CustomFunctionAsync(int param1, Func<string, Task<string>> processingFunc = null)
{
string result = null;
if (processingFunc != null)
result = await processingFunc("https://www.google.com/");
}


public async Task<string> LocalFunc(string url)
{
// processing...
}