2016-11-12 3 views
-1

Мне хорошо известно, что асинхронная синхронизация не рекомендуется. Причины имеют смысл.Асинхронная синхронизация выполняется лучше?

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

В целом, для контроллера Web-API:

  • асинхронного над синхронизацией появился для запуска всех запросов параллельно.
  • обычный код побежал до пяти (5) запросы параллельно.

Учитывая повторение Q & Как и коллективная литература, мой вывод об использовании асинхронной синхронизации по производительности должен быть ошибочным. Можете ли вы объяснить поведение, которое я видел? Я подозреваю, что ответ кроется в том, как я установил свою локальную систему, но я был бы признателен тем, кто более осведомлен, чем я, управляющий гаммой.


«Асинхронный над синхронизацией» будет что-то вроде этого:

public async Task SyncAsync() 
{ 
    return new Task(() => Thread.Sleep(2000)); 
} 

По sources:

Это бессмысленно, поскольку вы просто разгрузку работы от одного ThreadPool потока к другому ,

Так что я мог бы также написать это:

public void Sync() 
{ 
    Thread.Sleep(2000); 
} 
+0

Был ли мой вопрос непонятным? Мой ответ уже существует где-то еще? Или я просто рисую близкие и низкие голоса, потому что само упоминание о «асинхронной синхронизации» отвратительно для вас? – ricksmt

+0

Что означает «асинхронная синхронизация»? – Enigmativity

+4

Не могли бы вы поставить пример кода? – dotnetstep

ответ

1

Update 1 Вы пытаетесь сказать, что Асинхронный выполнить весь запрос параллельно, но в этом случае он будет передавать работу пул потоков для нить.

  1. Я был объяснить ниже, как хорошо, но понимаю, что все ваш запрос относительно некоторое API вызова или некоторый вызов ввода/вывода в этом случае вы служите больше запроса, но в случае синхронизации вы только сервер 5 запроса в качестве текущего потока это блок.

В Выше я предположу, что пул потоков имеет Capicity из 5.

Поэтому, когда 6 запроса пришел он будет ждать в случае синхронизации. В случае async, поскольку все 5 запросов в пуле потоков ввода-вывода имеют бесплатный запрос на сервер 6. Таким образом, это увеличивает пропускную способность приложения.

Также вы должны убедиться, что задача не является нитью. Задача и поток разные.


Я прохожу мимо генерала здесь и лучше всего, что я измерял во время своего развития.

  1. Async/Await - не серебряная пуля для улучшения характеристик. Вы должны выполнить его правильно. Async/Await следует использовать, когда выполняемая задача выполняется на основе ввода-вывода, например, при вызове базы данных, вызове веб-службы или вызове файловой системы. В этом случае это дает выгоду, поскольку операция ввода-вывода не требует потока, и это необязательно блокирует один поток.

  2. Если вы выполняете задачу с интенсивным процессором в async/await, это не даст вам преимуществ в производительности.

  3. Также вы должны проверить свое приложение под различными нагрузками. Например, если вы размещаете свое приложение IIS и локально вы тестируете с помощью отладки, тогда всегда меньше ресурсов, тогда вы чувствуете, что Sync хорош, поскольку они получают бесплатный ресурс, но когда вы увеличиваете нагрузку (как и многие пользователи за один раз), тогда создайте узкое место в Sync, как будто он не найдет свободный поток, и запрос не будет работать, хотя внутри потока IIS ожидает завершения ввода-вывода.

https://msdn.microsoft.com/en-us/magazine/hh456402.aspx

https://msdn.microsoft.com/en-us/magazine/jj991977.aspx

+0

Я не уверен, что вы поняли мой вопрос. Я попытаюсь изменить это. И я буду работать на MCV на следующей неделе: у меня заканчивается время. – ricksmt

+0

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

0

Я вижу из вашей дискуссии с dotnetstep вы пытаетесь собрать приложение MVC, но я не думаю, что мне нужно видеть, что для ответа на ваш вопрос. Ответ Dotnetstep верен, но я хотел бы уточнить некоторые дополнительные вопросы, которые вы сделали в своих комментариях.

Я хочу, чтобы понять, где что пул потоков 5 поступает из

То есть просто произвольное число dotnetstep выбрал. Это число будет поступать из раздела processModel> maxWorkerThreads файла web.config. Это число одновременно выполняемых запросов ASP.NET. Этот номер поощряет разработчиков к минимизации времени выполнения запросов. Например, если это число равно 5, то ASP.NET может обрабатывать 5 запросов одновременно. Но что будет, если запрос зависит от какой-либо другой операции ввода-вывода? Что делать, если вам нужно позвонить в веб-службу?

В сценарии «Синхронизация», когда «Request1» входит и вызывает веб-службу, поток Request1 будет ждать ответа от веб-службы. То же самое для Request2, Request3, Request4 и Request5. Когда Request6 приходит на сервер, он вернет ответ HTTP 503 («service unavailable»), поскольку все 5 потоков ждут ответа веб-службы. На этом этапе ваш сервер не может обрабатывать больше запросов до тех пор, пока один из запросов не будет завершен, и поток не будет возвращен в пул потоков.

В сценарии «Async» Request1 входит и вызывает веб-службу, поток Request1 НЕ будет ждать ответа от веб-службы, но сразу же вернется в пул потоков. То же самое для Request2, Request3, Request4 и Request5. Когда Request6 приходит, на сервере есть все 5 потоков (при условии, что ни один из вызовов веб-служб не вернулся) для обработки запроса. Это преимущество «Async», потому что оно не блокирует поток. Таким образом вы можете обрабатывать больше запросов одновременно.

Как вы можете ясно видеть это, все зависит от того, что вы делаете в запросе. Если запрос выполняет работу, которая требует чистого внимания к ЦП (интенсивная работа с ЦП), то async не поможет вам, так как это асинхронный или синхронизированный, процессор занят и больше ничего не может сделать. Поэтому ваш запрос будет ждать. Обратите внимание на то, что вы делаете в своей работе Async.Если все ваши дела для целей тестирования является:

Thread.Sleep(2000); 

тогда ваш поток все еще хранится занят ли это синхронизация или асинхронный (есть только один способ нить может спать, он не может спать и делать работу в то же время путем возврата в пул потоков).

Сделайте то, что действительно асинхронно, например, прочитайте из большого файла, и вы увидите реальную выгоду или асинхронную синхронизацию.

и почему он отличается от пула потоков, который он выгружает.

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

Update 1:

Немного больше информации, которая может быть полезным, когда у вас есть такой код:

return new Task(() => Thread.Sleep(2000)); 

Если приведенный выше код обрабатывается ниткой Request1, он будет переложена другой поток (Request1, Request2, Request3 или Request4). И эта другая нить будет спать. Так что, по сути, это стоит вам больше, потому что вы переключили контексты, но вы ничего не получили взамен. Поэтому из-за переключения контекста ваша асинхронная версия будет медленнее, чем ваша версия синхронизации.

Кроме того, имейте в виду, что время ожидания клиента будет почти таким же, будь то синхронизация или асинхронность (это не будет сделано быстрее). Единственное преимущество заключается в том, что ваш сервер может обрабатывать больше запросов. Работа по-прежнему должна быть выполнена так или иначе (синхронизация или асинхронный режим).

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