2015-04-01 2 views
0

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

public virtual ActionResult Method() 
{ 
    SomeLogic.LargeOperation(); 
    return View(...); 
} 

LargeOpertation делает много. Вот псевдокод:

public void LargeOpertion() { 
    DatabaseManipulations1(); 
    IndependentWork(); 
    CallingToWebService1(); 
    IndependentWork();  
    DatabaseManipulations2(); 
    IndependentWork(); 
    CallingToWebService2(); 
    IndependentWork(); 
} 

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

public virtual Task<ActionResult> Method() 
{ 
    await SomeLogic.LargeOperation(); 
    return View(...); 
} 

public async Task LargeOpertion() { 
    await DatabaseManipulations1(); 
    IndependentWork(); 
    await CallingToWebService1(); 
    IndependentWork();  
    await DatabaseManipulations2(); 
    IndependentWork(); 
    await CallingToWebService2(); 
    IndependentWork(); 
} 

Или я могу просто использовать задачу на LargeOpertaion так:

public virtual Task<ActionResult> Method() 
{ 
    await Task.Run(() => SomeLogic.LargeOperation()); 
    return View(...); 
} 

Давайте также предположим, что IndependentWork() не столь велика.

+0

Как долго длится/Мы говорим минут? 1 секунда? часы? – Phill

+1

Если 'LargeOperation' является асинхронным, пусть он возвращает' Task', в противном случае используется 'Task.Run (() => SomeLogic.LargeOperation());'. Кроме этого я не понимаю ваш вопрос. –

+0

Предположим, что в CallingToWebService1 есть операции, которые могут длиться около 2 минут, а в DatabaseManipulations1(), DatabaseManipulations2(), CallingToWebService2() 1 мин. – user3558203

ответ

4

Из-за некоторых проблем оптимизации я решил переписать метод действия контроллера на асинхронный.

Перед тем, как начать, вы должны понимать, что async будет делать для вас и то, что он не будет.

Асинхронные операции не работают быстрее. Таким образом, асинхронный вызов в базу данных происходит не быстрее, чем синхронный вызов базы данных.

await не возвращается в браузер раньше. Все, что он делает, это освободить текущий поток обратно в threadpool ASP.NET.

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

asyncis help with is scalability - то есть способность вашего приложения обрабатывать больше запросов с одинаковыми ресурсами. Тем не менее, это только помогает масштабируемость вашего веб-приложения - он не может волшебным образом попасть в вашу базу данных и сделать , что шкала. Итак, если ваше узкое место в масштабируемости - это ваша база данных, а не ASP.NET (как правило, это так), то async не поможет вам вообще.

Если ваши базовая база данных является масштабируемой (например, NoSQL, Azure SQL, или базы данных кластера), и если вашего приложения ASP.NET необходимо расширять, то вы можете воспользоваться async.

Должен ли я сделать все асинхронным и использовать в почти каждом слое приложения?

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

Однако ни в коем случае не следует использовать Task.Run или Task.Factory.StartNew. Вместо этого используйте истинные асинхронные API, такие как поддержка async в EF6.

+0

К сожалению, в какой-то момент мне нужно использовать Task.Run, потому что я использую api, у которого нет поддержки async (в случае EF, конечно, я могу использовать их поддержку async). Следовательно, у меня есть сомнения, где я должен его использовать, так как мне это нужно. Не могли бы вы объяснить, почему лучше всего использовать листья? – user3558203

+0

@ user3558203: Нет смысла использовать 'Task.Run' на ASP.NET. Это не поможет вам масштабировать. –

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