【问题标题】:PageAsyncTask in webforms button click never executesWebforms 按钮单击中的 PageAsyncTask 永远不会执行
【发布时间】:2020-10-02 10:52:44
【问题描述】:

我需要从 asp.net webforms 按钮单击事件处理程序执行异步操作。我已阅读文档 Using Asynchronous MethodsWhat not to do in ASP.NET。第一个文档链接在Page_Load 中显示了PageAsyncTask,并且不包括点击事件等事件。第二个文档链接涵盖了我的情况。

  • 我的网络表单声明为Async="true"
  • 我的 web.config http 运行时设置为 dotnet 4.5 httpRuntime targetFramework="4.5"

这是我的按钮点击事件处理程序:

protected void DoAsync_Click(object sender, EventArgs e)
{
    // This line executes
    Page.RegisterAsyncTask(new PageAsyncTask(async () =>
    {
        // This line never executes
        var stringToRead = "This line never executes";

        using (StringReader reader = new StringReader(stringToRead))
        {
            var readText = await reader.ReadToEndAsync();
            Result.Text = readText;
        }
    }));
    
    // This line executes
    HttpContext.Current.Response.Redirect(_someUrl, true);
}

我的问题是PageAsyncTask 任务中的代码永远不会执行。我在注册任务后尝试添加Page.ExecuteRegisteredAsyncTasks();,但它仍然没有执行。

我还尝试过将事件处理程序设置为 async void(不推荐)并以传统的 async/await 模式等待异步操作。这会导致 ThreadAbortedExceptions 并且无论如何都不是网络表单的推荐方法。

【问题讨论】:

  • 尝试将整个执行放在一个 Task.Run() 构造中: var t = Task.Run(() => {...}) t.Wait();
  • 这可以解决它,但它也会阻塞线程,这是我试图避免的。
  • 如果您无条件重定向,异步执行此操作有什么意义?
  • 这个例子不是真正的代码,它只是一个例子。真正的代码有几个数据库操作。关键是不要阻塞等待长时间运行的操作完成的线程。异步代码不是问题,问题是为什么它没有被执行。

标签: c# asp.net asynchronous async-await webforms


【解决方案1】:

我误解了PageAsyncTask 何时会被执行。问题是Page.RegisterAsyncTask 之后的重定向。重定向是在PageAsyncTask 之前执行的。

将重定向放在PageAsyncTask 中解决了这个问题。

protected void DoAsync_Click(object sender, EventArgs e)
{
    Page.RegisterAsyncTask(new PageAsyncTask(async () =>
    {
        var stringToRead = "This line never executes";

        using (StringReader reader = new StringReader(stringToRead))
        {
            var readText = await reader.ReadToEndAsync();
            Result.Text = readText;
        }

        HttpContext.Current.Response.Redirect(_someUrl, true);
    }));
}

【讨论】:

  • 如果你的代码中有一个 await ,那么你只是在等待,你不需要异步读取文件。该页面不能等待后面的代码。如果任务需要 30 秒,那么您的代码可以启动异步任务,但网页和代码不能等待。网页必须返回客户端往返。如果进程将完成(比如 30 秒后),那么您的问题是此时异步任务无法更新已经位于客户端浏览器上的网页。要更新,您需要一个 js 计时器 + ajax 调用并检查一些 session() 值
  • 感谢您的评论,但这样做的原因不是等待,而是不阻塞线程。如果我在按钮单击中放置同步长时间运行的任务,则线程在运行时被阻塞。如果它是异步的,那么该线程可以在操作完成时在其他地方使用。您对 AJAX 的看法是正确的——那将是一种替代解决方案。我主要关心的是为什么 PageAsyncTask 没有运行,而不是概念/架构问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-06-03
  • 1970-01-01
  • 1970-01-01
  • 2019-12-07
  • 1970-01-01
  • 2020-01-23
  • 2021-08-19
相关资源
最近更新 更多