2013-09-10 3 views
2

В настоящее время я пытаюсь сделать часть кода, написанную на VS 2012, используя Microsoft.Bcl.Async и .NET 4.0, работать в VS 2010. Для VS 2010 Я установил Async CTP (версия 3), так что я могу скомпилировать свой проект, написанный на V S2012.Различия между Async CTP и Bcl.Async при вызове методов async как синхронизация

После довольно много хлопот получать пакет Асинхронный CTP работать, сейчас я могу скомпилировать мой проект в рамках как VS 2012, а также VS 2010.

Однако, я вижу некоторые различия в том, как код работает во время выполнения. Код я упражнение показан ниже:

public class Fetcher 
{ 
    public string RunTask() 
    { 
     Task<string> task = TaskEx.Run(() => RunTaskAsync()); 
     return task.Result;      
    } 

    public async Task<string> RunTaskAsync() 
    { 
     await TaskEx.Delay(1); 
     return "Hello"; 
    }   
} 

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

Проблема: При запуске кода из VS 2012 оба метода вернут результат «Привет», и что еще более важно, оба метода будут корректно завершаться. Однако запуск кода из VS 2010 - это совсем другая история. Метод async работает так, как предполагалось, но метод оболочки sync просто зависает, и результат никогда не создается.

Поскольку я довольно новичок в концепции TPL и async/wait, у меня возникают проблемы с объяснением поведения, которое я вижу здесь. Есть ли какие-то ограничения в Async CTP, которые срабатывают, что я не знаю, или я делаю это концептуально неправильно?

ответ

4

Как правило, synchronous wrappers around asynchronous methods are strongly discouraged. Когда вы используете подход Result, вы run the risk of deadlock (как я описываю в своем блоге); Кроме того, Result перенесет любые исключения, что значительно затруднит обработку ошибок.

Поэтому я бы сказал: «Не делай этого».

Что касается Async CTP, существует множество ошибок, которые, как известно, существуют (плюс еще несколько, которые не являются общедоступными). И они не будут исправлены. I сильно рекомендуется обновить всех до VS2012.

Для этой конкретной проблемы это может быть связано с производительностью. Например, Task.Delay(1) возвращает задачу, которая будет выполнена почти сразу, поэтому между стартом задержки и состоянием гонки существует условие гонки, а await проверяет, завершена ли задача. Таким образом, возможно, что улучшения производительности в официальном Microsoft.Bcl.Async вызывают разницу в поведении.

+0

Спасибо за ваше объяснение Стивен, это имеет смысл! Я просто прочитал сообщение в блоге Стивеном Тубом, и я могу понять, почему оболочка синхронизации может быть не лучшим вариантом для большинства случаев. Кроме того, я согласен со своей стороны с Async CTP и обновлением до VS 2012. Но в настоящее время я должен заставить его работать в VS 2010, к сожалению ... Тем не менее, одна вещь, которая все еще беспокоит мой разум, заключается в том, что sync wrapper не работает, как я ожидал. Я следил за советом по использованию ConfigureAwait (false), но все равно не повезло. Кроме того, я увеличил задержку до 500 мс. –

 Смежные вопросы

  • Нет связанных вопросов^_^