Подтвердить что ты не робот

Что такое подпись метода для передачи делегата async?

Недавно я вернулся на С# из области Objective-C, а ключевые слова async/wait в С# 5 выглядят круто. Но я все еще пытаюсь получить дескриптор правильного синтаксиса.

Я хочу объявить метод, который принимает асинхронный делегат в качестве параметра, но у меня возникают проблемы с правильной настройкой как вызывающего, так и синтаксического кода. Может ли кто-нибудь предоставить образец кода, показывающий объявление метода, вызов и вызов делегату?

Я думаю, что объявление будет выглядеть следующим образом. Обратите внимание, что эта функция не является асинхронной; т.е. его асинхронность не зависит от делегата.

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

Вызов будет выглядеть примерно так:

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

Конечно, ни один из этих компиляций и большинство образцов, которые я видел, не предполагают, что у кого-то есть поле или свойство, которое делегат, а не анонимный делегат, который я хотел бы использовать.

4b9b3361

Ответ 1

Функция, которая принимает делегат в качестве параметра, должна использовать именованный тип делегирования; в отличие от Objective-C, вы не можете объявить анонимный тип делегата inline в определении функции. Однако генерические действия Action < > и Func < > предоставляются так, что вам не нужно объявлять новый тип самостоятельно. В приведенном ниже коде я предполагаю, что делегат принимает один int в качестве параметра.

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

Если эта функция фактически ничего не делает с возвращенным объектом задачи (как и с приведенным выше кодом), вы можете вместо этого использовать Action<int> в качестве типа делегата. Если вы используете Action, вы все равно можете объявить асинхронный делегат (ниже), но возвращенный неявный объект Task игнорируется.

Синтаксис лямбда для вызова указанной функции прост и синтаксис, который вы использовали в вопросе, верен. Обратите внимание, что здесь не нужно указывать тип параметра, поскольку он может быть выведен следующим образом:

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

Вы также можете передать метод или делегировать переменную, если хотите, вместо использования синтаксиса лямбда:

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

Ответ 2

Тип возвращаемого значения метода Task, если тип возврата отсутствует, или Task<T>, если существует тип возврата.

Tho, я не уверен на 100%, если у вас могут быть асинхронные лямбда.

В методе, который потребляет задачу, вы либо "ждете" задачу, либо используете свойства и методы в задаче для получения результата.