简体   繁体   English

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

[英]What's the method signature for passing an async delegate?

I've recently moved back to C# from being in Objective-C land, and the async/await keywords in C# 5 look cool.我最近从 Objective-C 领域移回 C#,C# 5 中的 async/await 关键字看起来很酷。 But I'm still trying to get a handle on the proper syntax.但我仍在努力掌握正确的语法。

I want to declare a method that takes an asynchronous delegate as a parameter, but I am having trouble getting both the caller and the callee syntax correct.我想声明一个将异步委托作为参数的方法,但是我无法正确获取调用方和被调用方的语法。 Can someone provide a code sample showing the method declaration, the call, and a call to the delegate?有人可以提供显示方法声明、调用和对委托的调用的代码示例吗?

I'm thinking the declaration would be something like the following.我认为声明将类似于以下内容。 Note that this function isn't asynchronous;请注意,此函数不是异步的; ie its asynchronicity is independent of the delegate.即它的异步性独立于委托。

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

The call would be something like:调用将类似于:

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

Of course none of this compiles and most of the samples I've seen assume that one has a field or property that's the delegate, rather than the anonymous delegate I'd like to use.当然,这些都不能编译,而且我见过的大多数示例都假设一个字段或属性是委托,而不是我想使用的匿名委托。

A function that takes a delegate as a parameter must use a named delegate type;将委托作为参数的函数必须使用命名委托类型; unlike in Objective-C you can't declare an anonymous delegate type inline in the function definition.与 Objective-C 不同,您不能在函数定义中内联声明匿名委托类型。 However, the generics Action<> and Func<> are provided so that you don't have to declare a new type yourself.但是,提供了泛型 Action<> 和 Func<>,因此您不必自己声明新类型。 In the code below I'm assuming the delegate takes a single int as a parameter.在下面的代码中,我假设委托将单个int作为参数。

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

If this function doesn't actually do anything with the Task object returned (as with the code shown above), you can instead use Action<int> as the delegate type.如果此函数实际上没有对返回的 Task 对象执行任何操作(如上面显示的代码),则可以改为使用Action<int>作为委托类型。 If you use Action, you can still declare the delegate async (below) but the implicit Task object returned is ignored.如果您使用 Action,您仍然可以声明委托 async(如下),但返回的隐式 Task 对象将被忽略。

The lambda syntax for calling the above function is straightforward and the syntax you used in the question is correct.调用上述函数的 lambda 语法很简单,您在问题中使用的语法是正确的。 Note that the parameter type doesn't need to be specified here since it can be inferred:请注意,这里不需要指定参数类型,因为它可以推断:

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

You can also pass a method or delegate variable, if you wish, instead of using the lambda syntax:如果愿意,您还可以传递方法或委托变量,而不是使用 lambda 语法:

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

If I have a task that I want to be passed but not executed, I can wrap the Task in a Func<> , then call that Func<> to create that task.如果我有一个想要传递但不执行的任务,我可以将 Task 包装在Func<> ,然后调用该Func<>来创建该任务。 The await can be used in the normal way.可以以正常方式使用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;
    }
}

The return type of the method signatue is Task if there is no return type, or Task<T> if there is a return type.如果没有返回类型,则方法签名的返回类型为Task如果有返回类型,则为Task<T>

Tho, I'm not 100% certain if you can have async lambdas like that. Tho,我不能 100% 确定您是否可以拥有这样的异步 lambda。

In the method that is consuming the task, you would either 'await' the task or use the properties and methods on Task to get the result.在使用任务的方法中,您可以“等待”任务或使用 Task 上的属性和方法来获取结果。

Please take a look to this example, with Task and an additional parameter.请查看此示例,其中包含 Task 和一个附加参数。 I hope this can help people understanding how to implement it...我希望这可以帮助人们了解如何实施它...

// ... more code ...

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

// ... more code ...

Declared functions:声明的功能:

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...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM