Після цього питання мені стає зручно при використанні операцій з асинхронізацією в ASP.NET MVC. Отже, я написав два повідомлення про це:
У мене занадто багато непорозумінь щодо асинхронних операцій на ASP.NET MVC.
Я завжди чую це речення: додаток може краще масштабуватися, якщо операції виконуються асинхронно
І я чула дуже багато таких пропозицій: якщо у вас величезний обсяг трафіку, вам може бути краще не виконувати запити асинхронно - споживання 2 додаткових потоків для обслуговування одного запиту відбирає ресурси від інших вхідних запитів.
Я думаю, що ці два речення непослідовні.
У мене не так багато інформації про те, як працює нитка пулів на ASP.NET, але я знаю, що потоковий пул має обмежений розмір для потоків. Отже, друге речення має бути пов'язане з цим питанням.
І мені хотілося б знати, чи використовує асинхронні операції в ASP.NET MVC нитку з ThreadPool на .NET 4?
Наприклад, коли ми реалізовуємо AsyncController, як структурується програма? Якщо я отримую величезний трафік, чи корисно реалізувати AsyncController?
Чи є хтось там, хто може зняти цю чорну завісу перед моїми очима і пояснити мені угоду про асинхронію на ASP.NET MVC 3 (NET 4)?
Редагувати:
Я читав цей документ майже сотні разів і розумію основну угоду, але все-таки маю плутанину, оскільки там надто багато непослідовних коментарів.
Використання асинхронного контролера в ASP.NET MVC
Редагувати:
Припустимо, у мене є дії контролера, як показано нижче (але це не реалізація AsyncController
):
public ViewResult Index() {
Task.Factory.StartNew(() => {
//Do an advanced looging here which takes a while
});
return View();
}
Як ви бачите тут, я запускаю операцію і забуваю про неї. Потім я повертаюся негайно, не чекаючи, коли це буде завершено.
У цьому випадку, чи має це використовувати нитку з нитки? Якщо так, після його завершення, що відбувається з цією ниткою? Чи GC
заходить та чиститься відразу після його завершення?
Редагувати:
Для відповіді @ Darin, ось зразок коду асинхронізації, який спілкується з базою даних:
public class FooController : AsyncController {
//EF 4.2 DbContext instance
MyContext _context = new MyContext();
public void IndexAsync() {
AsyncManager.OutstandingOperations.Increment(3);
Task<IEnumerable<Foo>>.Factory.StartNew(() => {
return
_context.Foos;
}).ContinueWith(t => {
AsyncManager.Parameters["foos"] = t.Result;
AsyncManager.OutstandingOperations.Decrement();
});
Task<IEnumerable<Bars>>.Factory.StartNew(() => {
return
_context.Bars;
}).ContinueWith(t => {
AsyncManager.Parameters["bars"] = t.Result;
AsyncManager.OutstandingOperations.Decrement();
});
Task<IEnumerable<FooBar>>.Factory.StartNew(() => {
return
_context.FooBars;
}).ContinueWith(t => {
AsyncManager.Parameters["foobars"] = t.Result;
AsyncManager.OutstandingOperations.Decrement();
});
}
public ViewResult IndexCompleted(
IEnumerable<Foo> foos,
IEnumerable<Bar> bars,
IEnumerable<FooBar> foobars) {
//Do the regular stuff and return
}
}