2014-09-15 2 views
1

У меня есть облачное приложение, которое использует отличную библиотеку WURFL для обнаружения устройств.AWAITing критическое свойство

Основываясь на типе устройства, которое обращается к веб-сайту, мы загружаем разные ресурсы.

До недавнего времени я внедрял сервис в своем Облачном приложении. Проблема в том, что она добавляет 3-5 минут к каждой процедуре отладки, поскольку служба поддерживает обнаружение многих тысяч устройств. Рекомендуемая модель командой .NET является загрузка службы в кэш:

var wurflDataFile = HttpContext.Current.Server.MapPath(WurflDataFilePath); 
var configurer = new InMemoryConfigurer().MainFile(wurflDataFile); 
var manager = WURFLManagerBuilder.Build(configurer); 
HttpContext.Current.Cache["WurflManagerCacheKey"] = manager; 

Это 3-5 минут задержка обходится нам примерно 1-3 часов полезного времени по команде 5 разработчиков (Люди получают до получения закуски и т. д. при каждом развертывании, будь то локально или в СИЗ)

Чтобы ускорить процесс, мы недавно создали независимую службу Cloud WEB API, которая получает правильную информацию и возвращает объект со всеми нам нужна информация. Мы получаем отличное (менее 30 мс) время ответа от активной службы.

Проблема, с которой я столкнулся сейчас, заключается в том, что я не уверен, как мы лучше всего изменим нашу рутину загрузки.

Я мог бы сделать HomeController async и просто подождать, но это кажется опасным. Каков наилучший способ справиться с чем-то подобным?

public static async Task<Device> GetDevice(RequestInfo requestInfo) 
{ 
    var client = new HttpClient(); 
    client.BaseAddress = new Uri("http://mysiteurl.com"); 
    client.DefaultRequestHeaders.Accept.Add(
      new MediaTypeWithQualityHeaderValue("application/json")); 

    var response = await client.PostAsJsonAsync("/api/devicedetection", requestInfo); 

    if (response.IsSuccessStatusCode) 
    { 
     return await response.Content.ReadAsAsync<Device>(); 
    } 
    return new Device(Device.Default); 
} 

//Proposed Solution from team as it stands 
public async Task<ActionResult> Index(string id) 
{ 
    _device = await Device.GetDevice(Request.UserAgent); 
    try 
    { 
     if (!string.IsNullOrEmpty(_userName)) 
     { 
      Session.Add("CurrentDevice", _device); 
      ViewBag.DeviceType = _device.Type; 
      ViewBag.DeviceOs = _device.Os; 
     } 
    } 
    catch (Exception ex) 
    { 
     Response.Redirect("/Error"); 
    } 
    return View(); 
} 
+5

Похоже, вы уже имеют решение. Какова ваша проблема/вопрос? – Servy

+0

Это приемлемый шаблон? Существует несколько дискуссий о контроллерах ASYNC. Что произойдет, если услуга занимает слишком много времени или идет вниз? Я чувствую, что у меня есть решение * A *, но это может быть не самое лучшее. – Wesley

ответ

5

Нет ничего плохого в использовании async-await на сайте. Если выполняемые вами операции естественно асинхронны (например, ввод-вывод), это намного предпочтительнее. Он снижает ресурсы, используемые вашим приложением, и повышает масштабируемость. *

Я бы рекомендовал держать в async стандарты именования и переименования GetDevice в GetDeviceAsync, а также обработки исключений путем перемещения _device = await Device.GetDevice(Request.UserAgent); внутри try-catch блока


* Это может немного увеличить продолжительность каждая операция, но она позволяет проводить намного больше операций одновременно

+0

@downvoter reason? – i3arnon

+0

Я не спустил вас вниз, но я мог бы не согласиться с вашей заметкой о ноте: «Это может немного увеличить продолжительность каждой операции». Зачем это делать? – avo

+1

@avo механизм 'async' (государственная машина, задачи и т. Д.) Действительно поставляется с некоторыми, очень маленькими затратами. 'async-await' - это не ускорение операций, а улучшение использования ресурсов и отключение работы специальных потоков (например, поток GUI). Подробнее в [Async Performance: ознакомление с расходами Async и Await] (http://msdn.microsoft.com/en-us/magazine/hh456402.aspx) – i3arnon

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