【问题标题】:How to use async/await to achieve asynchronous page in asp.net webform?asp.net webform中如何使用async/await实现异步页面?
【发布时间】:2012-03-22 15:05:31
【问题描述】:

我们现在可以在 ASP.NET MVC 4 中使用 async/await 关键字了。

public async Task<ActionResult> TestAsync()
{
    WebClient client = new WebClient();
    return Content(await client.DownloadStringTaskAsync("http://www.google.com"));
}

但是如何在 ASP.NET WebForms 中使用它呢?

【问题讨论】:

    标签: asp.net asynchronous webforms async-await


    【解决方案1】:

    一种简单的方法是让您的事件处理程序async。首先,将Async="true" 参数添加到@Page 指令中,然后您应该能够编写异步事件处理程序:

    protected async void Page_Load(object sender, EventArgs e)
    {
      var client = new WebClient();
      var content = await client.DownloadStringTaskAsync("http://www.google.com");
      Response.Write(content);
    }
    

    我说“应该可以”是因为我自己还没有真正尝试过。但它应该可以工作。

    更新:适用于Page_Load(请参阅this MSDN forum thread),但应该适用于其他事件,例如按钮点击。

    更新:确实适用于 ASP.NET 4.5 中的 Page_Load。此外,他们还添加了检查您是否不当使用async 事件处理程序。 See this video for details.

    【讨论】:

    • 如果 await 关键字没有通知 Page 类关于 Page_Load 中的异步操作,为什么按钮点击会有任何不同?但是感谢您提供现在支持的更新。
    • 其实是因为async void周围的问题。设计时考虑到 async 的系统(例如,WebAPI 和 MVC 的某些部分)专门使用 Tasks。 async void 只通知SynchronizationContext,在这种情况下,它是 ASP.NET 运行时的一部分(位于 WebPages/MVC/WebAPI 下方)。
    • 如果您注册它们,那应该可以正常工作。但是async void 没有向Page 注册自己,因此出现了问题(在.NET 4.0 上)。
    • 根据hanselman.com/blog/…,在 Web 表单中使用异步的唯一可靠方法是注册 Page.RegisterAsyncTask。您确定将 async 添加到 Page_Load 就足够了吗?
    • @MichaelFreidgeim:够了。虽然我推荐RegisterAsyncTask
    【解决方案2】:

    根据http://www.hanselman.com/blog/TheMagicOfUsingAsynchronousMethodsInASPNET45PlusAnImportantGotcha.aspx,在 Web 表单中使用异步的唯一可靠方法是调用 Page.RegisterAsyncTask。

    支持异步Page_Load等简单事物的代码非常 复杂且没有经过基本场景之外的任何测试。

    将 async 与 void 一起使用是不稳定或不可靠的。然而,你们都 所要做的就是调用 Page.RegisterAyncTask - 这不是任何麻烦,而且 你会在一个更好更灵活的地方

    .

    public void Page_Load(object sender, EventArgs e)
    {
        RegisterAsyncTask(new PageAsyncTask(LoadSomeData));
    }
    
    public async Task LoadSomeData()
    {
    var clientcontacts = Client.DownloadStringTaskAsync("api/contacts");
    var clienttemperature = Client.DownloadStringTaskAsync("api/temperature");
    
    var contacts = Newtonsoft.Json.JsonConvert.DeserializeObject>(await clientcontacts);
    var temperature = Newtonsoft.Json.JsonConvert.DeserializeObject(await clienttemperature);
    
    listcontacts.DataSource = contacts;
    listcontacts.DataBind();
    Temparature.Text = temperature; 
    }
    

    【讨论】:

    • 是的,但它不等待异步任务完成并转到 Page_Load 中的下一行代码。
    猜你喜欢
    • 1970-01-01
    • 2012-02-06
    • 2019-01-17
    • 2019-10-12
    • 2016-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-18
    相关资源
    最近更新 更多