我最近从Objective-C领域转回C#,而C#5中的async / await关键字看起来很酷。但我仍然试图掌握正确的语法。
我想声明一个将异步委托作为参数的方法,但是我无法使调用者和被调用者语法都正确。有人可以提供代码示例,显示方法声明,调用和对委托的调用吗?
我认为声明将如下所示。请注意,此函数不是异步的;即它的异步性独立于代表。
void DoSomethingWithCallback(async delegate foo(int))
{
...
foo(42);
...
}
电话会是这样的:
DoSomethingWithCallback(async (int x) => { this.SomeProperty = await SomeAsync(x); });
当然,这些都没有编译,我见过的大部分样本都假设有一个字段或属性是委托,而不是我想使用的匿名委托。
答案 0 :(得分:59)
将委托作为参数的函数必须使用命名委托类型;与Objective-C不同,您不能在函数定义中声明内联的匿名委托类型。然而,仿制药Action<>和Func<>提供,以便您不必自己声明新类型。在下面的代码中,我假设委托只使用一个int
作为参数。
void DoSomethingWithCallback(Func<int,Task> callbackDelegate)
{
Task t = callbackDelegate(42);
}
如果此函数实际没有返回任何返回的Task对象(与上面显示的代码一样),则可以使用Action<int>
作为委托类型。如果使用Action,仍然可以声明委托async(下面),但忽略返回的隐式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.
}
答案 1 :(得分:7)
如果我有一个要传递但不执行的任务,则可以将该任务包装在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;
}
}
答案 2 :(得分:6)
如果没有返回类型,方法signatue的返回类型为Task
,如果有返回类型,则返回Task<T>
。
所以,如果你能有像这样的异步lambda,我不是百分之百确定。
在使用该任务的方法中,您将“等待”该任务或使用Task上的属性和方法来获取结果。