Как вернуть значение T из BeginInvoke? - PullRequest
1 голос
/ 09 января 2012

Я хочу написать класс для упрощения асинхронного программирования, например: строка s = mylib.BeginInvoek (test, "1"); вот мой код:

   public T BeginInvokeExWithReturnValue<T>(Func<T> actionFunction)
    {
        ExecWithReturnType<T> execWtihReturnValue = new ExecWithReturnType<T>(actionFunction);
        IAsyncResult iar = execWtihReturnValue.BeginInvoke(new AsyncCallback(EndInvokeExWithReturnValue<T>), execWtihReturnValue);
        // how to code here to return value
    }

    private void EndInvokeExWithReturnValue<T>(IAsyncResult iar)
    {
        ExecWithReturnType<T> execWtihReturnValue = (ExecWithReturnType<T>)iar.AsyncState;
        execWtihReturnValue.EndInvoke(iar);
    }

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

Ответы [ 3 ]

6 голосов
/ 09 января 2012

То, что вы пытаетесь сделать прямо сейчас, не асинхронно;если вы хотите вернуть T, просто используйте:

return actionFunction();

Это будет меньше накладных расходов.

Если вы хотите асинхронно, и вы на 4.0, тогда TPL может быть хорошим вариантом:

public Task<T> BeginInvokeExWithReturnValue<T>(Func<T> actionFunction)
{
    var task = new Task<T>(actionFunction);
    task.Start();
    return task;
}

Теперь вызывающая сторона может использовать:

var task = BeginInvokeExWithReturnValue(() => Whatever());

, а затем, при желании, проверить завершение, заблокировать (Wait) длязавершение, регистрация продолжений и т. д. Или просто:

var result = task.Result; // implicit wait
Console.WriteLine(result);

Это позволяет без проблем писать асинхронный код.Или в C # 5.0 легко написать продолжение:

var result = await task; // continuation - this is **not** a wait
Console.WriteLine(result);
0 голосов
/ 09 января 2012

Исходя из комментариев,

В .NET

APM есть 3 модели асинхронной разработки - (BeginXXX EndXXX), которые вы используете здесь, когда долго выполняющаяся задача вызывает ееобратно в ваш код в методе EndXXX

EAP - на основе событий.В этой модели, когда долгое выполнение задачи завершается, возникает событие для информирования вашего кода.

TPL - Новое в .NET 4, это версия на основе «Задачи».это больше всего похоже на синхронное программирование клиентского кода с использованием свободного интерфейса.Он вызывает ваш код с помощью continueWith.

Надеюсь, это поможет

0 голосов
/ 09 января 2012

Как отметил Дэвид, метод Invoke, вероятно, является тем, что вам нужно, но если вы хотите написать свой собственный вариант, вам просто нужно набрать приведение значения к универсальному (T, в вашем примере), чтобыудовлетвори свой комментарий.

return (T) iar;
...