带有 async/await 的 ASP.NET Webforms

F. *_*ber 6 asp.net asynchronous webforms async-await

我的基于 .Net 4.6 的 Webforms 应用程序必须非常广泛地使用 async/await 功能。因为我对这个 async/await 主题很陌生,所以我阅读了很多像这样这样的最佳实践。但是我仍然有一些问题,我还没有找到任何明确的信息。

  1. 关于页面生命周期事件:我知道例如对于 Page_Load-Event 最好的做法是避免异步无效方法并注册这样的方法:

    protected void Page_Load(object sender, EventArgs e)
    {
       PageAsyncTask pageAsyncTask = new PageAsyncTask(SomeAsyncMethod);
       Page.RegisterAsyncTask(pageAsyncTask);
       //Method to invoke the registered async-methods immedietly and not after the PreRender-Event
       Page.ExecuteRegisteredAsyncTasks();
     }
    
    Run Code Online (Sandbox Code Playgroud)

    我的问题是我想在注册后立即调用异步方法,而不是在 OnPreRender 事件之后调用。这应该通过调用 ExecuteRegisteredAsyncTasks() 方法来实现。但在我的情况下,这没有效果,并且在 PreRender 事件之后仍会调用异步方法。但为什么?

  2. 关于控制事件:是按照我在上面的代码示例中提到的相同方式注册异步方法更好,还是可以使用 async-void 签名,例如:

    protected async void OnClick(object sender, EventArgs e)
    {
    await SomeAsyncMethod();
    }
    
    Run Code Online (Sandbox Code Playgroud)

    我找到了两个例子,但没有明确的信息哪个是更好的解决方案以及为什么。

  3. 关于 Context 和 ConfigureAwait,最佳实践似乎是await SomeAsyncMethod.ConfigureAwait(false)为了获得更好的性能并且在上下文不重要的情况下使用它,而不是在上下文中使用它,例如在操作 GUI 元素时。但在我的情况下,如果我调用await SomeAsyncMethod.ConfigureAwait(false)我的点击事件似乎没有什么区别 。我仍然可以毫无问题地操作我的 GUI 元素。我使用的例子是这样的:

    private async void button1_Click(object sender, EventArgs e)
    {
      button1.Enabled = false;
      try
      {
        await SomeAsyncMethod().ConfigureAwait(false);
      }
      finally
      {
        //Manipulating still works even it's another context
        button1.Enabled = true;
      }
    }
    
    Run Code Online (Sandbox Code Playgroud)

所以我想知道为什么 GUI 元素的操作仍然有效,我是否真的应该在上下文不重要的每个异步方法上使用 ConfigureAwait(false),这很乏味。我想知道这是否与我用于 Web 应用程序的 Telerik 使用 Ajax 功能有关。但这只是一个假设。

Pau*_*ado 6

ASP.NET WebForms 有自己的异步执行引擎。请参阅文档

在任何情况下,您通常希望(或需要)返回事件处理程序等方法的当前同步上下文,因此您不应该调用ConfigureAwait(false)inside button1_Click,而应该调用 inside SomeAsyncMethod