Как мне вызвать асинхронный метод из ASPX-файла (не из codebehind)?

#c# #asp.net #async-await #webforms

#c# #asp.net #асинхронный-ожидание #веб-формы #асинхронное ожидание

Вопрос:

У меня есть библиотека DLL, которая содержит асинхронный метод для получения отчета. Он выполняет всю тяжелую работу, включая форматирование HTML.

 namespace MyReportEngine
{
    public class Renderer
    {
        static public async Task<string> GetReportHtml()
        {
            //Magic (not important)
        }
    }
}
  

Я хочу создать веб-сайт, не выполняя много работы. Все, что я хочу сделать, это создать простой ASPX-файл, который использует DLL. Я пробовал это:

 <%@ Assembly Name="MyAssembly" %>
<%@ Import Namespace="MyAssembly.MyReportEngine" %>
<%@ Page Async="true" %>

<html>
<body>
    <% =await Renderer.GetReportHtml() %>
</body>
</html>
  

Это приводит к исключению во время выполнения во время компиляции JIT:

 Compiler Error Message: BC36937: 'Await' can only be used when contained within a method or lambda expression marked with the 'Async' modifier.
  

Я проверил документацию и учебные пособия, подобные этому, но, похоже, они касаются только добавления асинхронных вызовов в codebehind. Нет никакой информации о том, как выполнить вызов из самой разметки ASPX. Возможно ли это?

Комментарии:

1. Вы пытаетесь открыть страницу, а затем динамически загрузить содержимое? Вероятно, вам потребуется преобразовать содержимое в AJAX.

2. Нет, я не пытаюсь открыть страницу, а затем динамически загружать содержимое. Я пытаюсь полностью отобразить страницу на стороне сервера.

3. ОК. Чем это то, что задокументировано: learn.microsoft.com/en-us/aspnet/web-forms/overview /…

Ответ №1:

Оберните это в отдельный метод, затем вызовите этот метод.

Ответ №2:

Избегайте размещения кода в разметке.

Для вашего варианта использования вы можете использовать буквальный элемент управления:

 <%@ Assembly Name="MyAssembly" %>
<%@ Import Namespace="MyAssembly.MyReportEngine" %>
<%@ Page Async="true" %>

<html>
<body>
    <asp:Literal id="ReportHtml" runat="server" />
</body>
</html>
  

Ответ №3:

Вы что-то упускаете Page.RegisterAyncTask ?

 public void Page_Load(object sender, EventArgs e)
{
    RegisterAsyncTask(new PageAsyncTask(GetReportHtml));
}
  

Ссылка: https://www.hanselman.com/blog/TheMagicOfUsingAsynchronousMethodsInASPNET45PlusAnImportantGotcha.aspx