await和async在一般处理程序中的使用

写在前面

有个小项目,前端使用的html页面,那服务端的业务处理就采用最简单的一般处理程序了,之前一直在用,觉得一直用一种方式,确实挺蛋疼的,之前也有了解过async和await的内容。就想着自己折腾折腾。

代码

前端ajax请求

复制代码
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>新年签到,赢奖品</title>
</head>
<body>
    <div id="dvMsg"></div>
</body>
</html>
<script src="Js/jquery-2.1.1.min.js"></script>
<script>
    $(function () {
        $.getJSON("Ashx/GetUserInfoAsync.ashx", function (data) {
            console.log(data);
            $('#dvMsg').html(data);
        });
    });
</script>
复制代码

一般处理程序

复制代码
  /// <summary>
    /// GetUserInfoAsync 的摘要说明
    /// </summary>
    public class GetUserInfoAsync : IHttpHandler
    {
        public async void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "text/plain";
            var name = await GetUserAsync();
            context.Response.Write(name);

        }
        private async Task<string> GetUserAsync()
        {
            return await Task.Run(() =>
            {
                return "异步handler";
            });
        }
        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
复制代码

以为这样就大功告成了。其实这才是悲剧的开始。

满足使用async和await的条件了?

调用的目标方法必须是async的。所以就想着在ProcessRequest方法前加个async就可以了吧。其实不然,在使用async的地方也有特别的要求。

 

详情

大概意思就是异步操作,只能在异步模块中进行。所以就很奇怪了。之前在控制台程序中,也是给Main方法直接添加async的。这里就不行了。

经过查找,发现这样的一个类

复制代码
using System;
using System.ComponentModel;
using System.Threading.Tasks;

namespace System.Web
{
    // 摘要: 
    //     提供方法,从而衍生的任务处理程序类可实施该方法以处理异步任务。
    public abstract class HttpTaskAsyncHandler : IHttpAsyncHandler, IHttpHandler
    {
        // 摘要: 
        //     从派生类中的构造函数中调用,用于初始化 System.Web.HttpTaskAsyncHandler 类。
        protected HttpTaskAsyncHandler();

        // 摘要: 
        //     当在派生类中重写时,将获取一个指示任务处理程序类实例是否可重用于另一异步任务的值。
        //
        // 返回结果: 
        //     如果重复使用处理程序,则为 true;否则为 false。 默认值为 false。
        public virtual bool IsReusable { get; }

        // 摘要: 
        //     当在派生类中重写时,将提供处理同步任务的代码。
        //
        // 参数: 
        //   context:
        //     HTTP 上下文。
        //
        // 异常: 
        //   System.NotSupportedException:
        //     方法实现但不提供任何默认用于异步任务的处理程序。
        [EditorBrowsable(EditorBrowsableState.Never)]
        public virtual void ProcessRequest(HttpContext context);
        //
        // 摘要: 
        //     当在派生类中重写时,将提供处理异步任务的代码。
        //
        // 参数: 
        //   context:
        //     HTTP 上下文。
        //
        // 返回结果: 
        //     异步任务。
        public abstract Task ProcessRequestAsync(HttpContext context);
    }
}
复制代码

发现这个抽象类实现自IHttpAsyncHandler, IHttpHandler这两个接口,肯定能满足需求了。那么接下来就对一般处理程序进行改造

复制代码
    /// <summary>
    /// GetUserInfoAsync 的摘要说明
    /// </summary>
    public class GetUserInfoAsync : HttpTaskAsyncHandler
    {
        private async Task<string> GetUserAsync()
        {
            return await Task.Run(() =>
            {
                return "异步handler";
            });
        }public override async Task ProcessRequestAsync(HttpContext context)
        {
            context.Response.ContentType = "text/plain";
            var name = await GetUserAsync();
            context.Response.Write(name);
        }
    }
复制代码

这样就很方便的将一般处理程序变成一个异步处理的了。

总结

没事折腾一下代码,最近在博客园中看到关于await和async的文章,另外手上也有一个项目,就想着能不能使用异步的方式。所以就有了这篇文章。

posted @   wolfy  阅读(6452)  评论(12编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
历史上的今天:
2014-12-23 [Js/Jquery]天气接口简单使用
点击右上角即可分享
微信分享提示