2015-03-30 3 views
1

Извините за вопрос для начинающих, я прочитал много сообщений здесь и в Интернете, и есть что-то интересное, которое я не могу понять.использование async в WebAPI со многими асинхронными вызовами

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

Мой проект состоит из нескольких огромных действий, которые много раз читали/вставляли/обновляли из БД EF6. действие выглядит так:

public async Task<HttpResponseMessage> Get(int id) 
    { 
    PolicyModel response = await policyRepository.GetPolicyAsync(id); 
    return Request.CreateResponse<PolicyModel>(HttpStatusCode.OK,response); 
    } 

и GetPolicyAsync (интермедиат идентификатор) выглядит следующим образом:

public async Task<PolicyModel> GetPolicyAsync(int id) 
    { 
     PolicyModel response = new PolicyModel(); 
     User currentUser = await Repositories.User.GetUserDetailsAsync(id); 

     if(currentUser.IsNew) 
     { 
     IEnumerable<Delivery> deliveries = await Repositories.Delivery.GetAvailableDeliveries(); 
     if(deliveries == null || deliveries.Count() == 0 
     { 
      throw new Exception("no deliveries available"); 
     } 
     response.Deliveries = deliveries; 
     Ienumerable<Line> lines = await Repositores.Delivery.GetActiveLinesAsync(); 
     lines.AsParallel().ForAll(line => { 
     await Repositories.Delivery.AssignLineAsync(line,currentUser); 
    } 
    ... 
     return response; 
    } 

Я не писал весь код, но он идет совсем немного, и он также разбит несколько методов, но это его дух

Теперь у меня есть вопрос: хорошо ли использовать столько ожидающих в одном методе? Я видел, что отлаживать сложнее, трудно ли поддерживать контекст нити и ради назначения работника, не следует ли мне просто использовать Task.Factory.StartNew() или, может быть, позвонить просто Task.Delay(), чтобы запрос был недвусмысленно перенаправлен рабочему ? Я знаю, что это не очень хорошая практика (асинхронная весь путь), так что, может быть, только один метод асинхронного в конце/Начального метод GetpolicyAsync(int id)

EDIT:

как я понял механику методов асинхронных in .net, для каждого метода async компилятор ищет свободный поток и позволяет ему иметь дело с этим методом, поток ищет бесплатного рабочего и назначает ему метод, а затем сообщает компилятору, что он является бесплатным. поэтому, если у нас есть 10 потоков, и для каждого потока есть 10 работников, программа может иметь 100 одновременных асинхронных методов. Итак, вернемся к веб-разработке, IIS присваивает поток x каждому пулу приложений, например 10. это означает, что метод async WebAPI может обрабатывать 100 запросов, но если внутри есть другой метод асинхронизации, количество запросов, которые могут быть дебетовыми, составляет 50 и т. д., правильно? и, как я понял, я должен вызвать метод асинхронного для того, чтобы сделать метод WebAPI истинно асинхронным и сейчас, так как это плохая практика, чтобы использовать Task.Factory.StartNew(), я должен по крайней мере использовать Task.Delay()

что я действительно хочу, чтобы получить является масштабируемость методов асинхронной WebAPI и контекст осознания синхронизированных методов

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

Thanks

+1

Нет «работника». Операция «async» не нуждается в «запуске». – i3arnon

+0

Вы спрашиваете, хорошо ли использовать 'await' много раз в том же методе? если да, то да. – i3arnon

ответ

0

После долгих поисков я наткнулся на этот artical: https://msdn.microsoft.com/en-us/magazine/dn802603.aspx

объясняет, что @ i3arnon сказал в комментарии. нет никаких рабочих, нитки выполняют всю работу.
Вкратце, поток, который обрабатывает веб-запрос, попадает в операционную систему, предназначенную для асинхронного использования в стеке драйверов, он создает запрос и передает его драйверу.
Водитель маркирует его как ожидающий и сообщает «сделано» в поток, который возвращается в пул потоков, чтобы получить другое назначение.
Фактическая работа выполняется не потоками, а водителем, который заимствует время процессора из всех потоков и оставляет их бесплатными для участия в их бизнесе.
Когда справка завершена, водитель уведомляет об этом, и доступная нить приходит для продолжения ...

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

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

модераторы, я настоящий новобранец, если у меня все получилось, пожалуйста, поправьте меня Спасибо!

2

Нет ничего плохого в том, чтобы иметь m любые await s одним способом. Если этот метод становится слишком сложным для вас, вы можете разбить его на несколько методов:

public async Task<PolicyModel> GetPolicyAsync(int id) 
{ 
    PolicyModel response = new PolicyModel(); 
    User currentUser = await Repositories.User.GetUserDetailsAsync(id); 

    if(currentUser.IsNew) 
    { 
     await HandleDeliveriesAsync(await Repositories.Delivery.GetAvailableDeliveries()); 
    } 
    ... 
    return response; 
} 

public async Task HandleDeliveriesAsync(IEnumerable<Delivery> deliveries) 
{ 
    if(deliveries == null || deliveries.Count() == 0 
    { 
     throw new Exception("no deliveries available"); 
    } 
    response.Deliveries = deliveries; 
    Ienumerable<Line> lines = await Repositores.Delivery.GetActiveLinesAsync(); 
    lines.AsParallel().ForAll(line => { 
    await Repositories.Delivery.AssignLineAsync(line,currentUser); 
} 

Не используйте Task.Factory.StartNew или Task.Delay, как это просто разгружает ту же работу в другой поток. В большинстве случаев это не добавляет никакой ценности и на самом деле вредит ASP.Net.

+0

Чтобы добавить к этому, если вы взломаете исходный код веб-API, вы увидите, что весь процесс маршрутизации запросов имеет несколько методов с несколькими ожиданиями в них. – moarboilerplate

+0

Большое вам спасибо @ i3arnon за то, что вы не отправили меня в художественный, я обновил свой вопрос, чтобы лучше объяснить мой пробел в моих знаниях. – armageddon

+0

Метод @armageddon 'async' не нуждается в фоновом потоке. Вы можете посмотреть на другие мои ответы для получения дополнительной информации: http://stackoverflow.com/a/28237602/885318 – i3arnon

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