Какая будет лучшая альтернатива для ключевого слова await в .NET 4.0? У меня есть метод, который должен возвращать значение после асинхронной операции. Я заметил, что метод wait() полностью блокирует поток, что делает асинхронную операцию бесполезной. Каковы мои возможности для запуска операции async при освобождении потока пользовательского интерфейса?
Ожидать альтернативы в .NET 4.0?
Ответ 1
Я думаю, что ваши основные параметры
-  Использование Taskи.ContinueWith()
-  Использование Async CTP и async/await
- Использование Реактивные расширения
Самый простой способ - установить Async CTP. Насколько мне известно, лицензия позволяет использовать коммерческое использование. Он исправляет компилятор и поставляется с DLL объемом 150 КБ, которые вы можете включить в свой проект.
Вы можете использовать Task и .ContinueWith(). Но это означает, что вам нужно предпринять некоторые усилия с обработкой exeption и контролем потока.
Задачи - это функциональная конструкция. Поэтому ContinueWith() не очень хорошо сочетается с императивными конструкциями, такими как циклы for или try-catch. Поэтому введены async и await, поэтому компилятор может помочь нам.
Если у вас нет такой поддержки компилятора (например, вы используете .Net 4.0), лучше всего использовать TAP вместе с функциональной структурой. Reactive Extensions - очень хорошая структура для обработки асинхронных методов.
Просто зайдите в Google для "реактивных задач расширения", чтобы начать.
Ответ 2
Вы можете реализовать поведение типа await с сопрограммами yield, я использую это в коде, отличном от 4.5. Вам нужен класс YieldInstruction, который извлекается из метода, который должен запускаться async:
public abstract class YieldInstruction
{
    public abstract Boolean IsFinished();
}
Затем вам понадобятся некоторые реализации YieldInstruction (a.e. TaskCoroutine, который обрабатывает задачу) и используют его таким образом (псевдокод):
public IEnumerator<YieldInstruction> DoAsync()
{
    HttpClient client = ....;
    String result;
    yield return new TaskCoroutine(() => { result = client.DownloadAsync(); });
    // Process result here
}
Теперь вам нужен планировщик, который обрабатывает выполнение инструкций.
for (Coroutine item in coroutines)  
{  
    if (item.CurrentInstruction.IsFinished())  
    {
         // Move to the next instruction and check if coroutine has been finished 
         if (item.MoveNext()) Remove(item);
    }
}
При разработке приложений WPF или WinForms вы также можете избежать любых вызовов Invoke, если вы обновляете сопрограммы в нужное время. Вы также можете расширить идею, чтобы сделать вашу жизнь еще проще. Пример:
public IEnumerator<YieldInstruction> DoAsync()
{
    HttpClient client = ....;
    client.DownloadAsync(..);
    String result;
    while (client.IsDownloading)
    {
        // Update the progress bar
        progressBar.Value = client.Progress;
        // Wait one update
        yield return YieldInstruction.WaitOneUpdate;
    }
    // Process result here
}
