Это необходимо для действия контроллера, который только возвращает представление, чтобы быть асинхронным? - PullRequest
0 голосов
/ 27 сентября 2018

Выполните это основное действие:

[HttpGet]
public IActionResult Index()
{
    return View();
}

Измените его, чтобы использовать async / await:

[HttpGet]
public async Task<IActionResult> Index()
{
    return await Task.Run(() => View());
}

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

Но на самом деле я не делаю ничего, кроме этой единственной вещи, котораявозвращая взгляд.Наличие ключевого слова async фактически представляет конечный автомат в скомпилированном коде, что добавляет сложности.

Стоит ли делать это действие асинхронным?Есть ли лучший способ изменить его, чтобы сделать его асинхронным?

Ответы [ 2 ]

0 голосов
/ 27 сентября 2018

Мне кажется, что вам следует вернуться к документу Microsoft TAP и получить более полное представление о том, как заставить задачу работать для вас.

В вашем примере:

public Task<IActionResult> Index()
{
    return Task.FromResult(View());
}

Этопросто возвращает некоторые HTML, Javascript и CSS, так что это будет бесполезно, а это означает, что при добавлении Task в обычную функцию возникают накладные расходы, которые могут стать дорогостоящими.

Теперь, если у вас было что-то вроде этого:

public Task<IActionResult> Index()
{
    var users  = DbContext.GetUsersAsync();
    var groups = DbContext.GetGroupsAsync();

     await Task.WhenAll(users,groups);

    var m = new Model(){
     Users = users.Result,
     Groups = groups.Result
    }

    return View(m);
}

В этом сценарии задача имеет смысл, вы по сути выполняете две разные функции ввода-вывода одновременно, а затем ожидаете всехиз них, чтобы закончить, прежде чем двигаться дальше.Вы берете количество времени, которое потребовалось бы для обработки каждого вызова по отдельности, и сокращаете его, вероятно, наполовину (за счет блокировки потенциального потока ЦП для другого «веб-пользователя» для доступа к тому же документу.)

 public Task<IActionResult> Index()
    {
        var users  = await DbContext.GetUsersAsync();
        var groups = await DbContext.GetGroupsAsync();

        var m = new Model(){
         Users = users,
         Groups = groups
        }

        return View(m);
    }

В моем третьем примере, несмотря на то, что он использует Async / Await, он по-прежнему выполняет все один за другим, тратя впустую драгоценные потоки.

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

https://docs.microsoft.com/en-us/dotnet/standard/asynchronous-programming-patterns/task-based-asynchronous-pattern-tap

0 голосов
/ 27 сентября 2018

Краткий ответ - Нет. Поскольку в View() ничего не происходит async, в выполнении нет мест, где компилятор может освободить поток, чтобы позволить другой работе происходить в том же потоке.

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

Единственное преимущество в async, которое я вижу, - это последовательность, если у вас есть много других действий, которые на самом деле используют async.Если вы действительно хотите, чтобы имела подпись Task<T> для целей согласованности, вы можете рассмотреть следующие вопросы:

public Task<IActionResult> Index()
{
    return Task.FromResult(View());
}

(Обратите внимание, что async ключевых слов не задействовано и Task.Run не раскручиваетновое задание для запуска)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...