异步HTTPHandler的实现

使用APM的方式实现

using System;
using System.Web;
using System.Threading;

class HelloWorldAsyncHandler : IHttpAsyncHandler
{
    public bool IsReusable { get { return false; } }

    public HelloWorldAsyncHandler()
    {
    }
    public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData)
    {
        context.Response.Write("<p>Begin IsThreadPoolThread is " + Thread.CurrentThread.IsThreadPoolThread + "</p>\r\n");
        AsynchOperation asynch = new AsynchOperation(cb, context, extraData);
        asynch.StartAsyncWork();
        return asynch;
    }

    public void EndProcessRequest(IAsyncResult result)
    {
    }

    public void ProcessRequest(HttpContext context)
    {
        throw new InvalidOperationException();
    }
}

class AsynchOperation : IAsyncResult
{
    private bool _completed;
    private Object _state;
    private AsyncCallback _callback;
    private HttpContext _context;

    bool IAsyncResult.IsCompleted { get { return _completed; } }
    WaitHandle IAsyncResult.AsyncWaitHandle { get { return null; } }
    Object IAsyncResult.AsyncState { get { return _state; } }
    bool IAsyncResult.CompletedSynchronously { get { return false; } }

    public AsynchOperation(AsyncCallback callback, HttpContext context, Object state)
    {
        _callback = callback;
        _context = context;
        _state = state;
        _completed = false;
    }

    public void StartAsyncWork()
    {
        ThreadPool.QueueUserWorkItem(new WaitCallback(StartAsyncTask), null);
    }

    private void StartAsyncTask(Object workItemState)
    {

        _context.Response.Write("<p>Completion IsThreadPoolThread is " + Thread.CurrentThread.IsThreadPoolThread + "</p>\r\n");

        _context.Response.Write("Hello World from Async Handler!");
        _completed = true;
        _callback(this);
    }
}

 

IIS 6.0 注册Handler

 

<configuration>
  <system.web>
<httpHandlers><add verb="*" path="*.SampleAsync" type="HelloWorldAsyncHandler"/></httpHandlers>
  </system.web>
</configuration>

 

IIS 7.0 注册handler 经典模式下

configuration>
  <system.web>
<httpHandlers><add verb="*" path="*.SampleAsync" type="HelloWorldAsyncHandler"/></httpHandlers>
  </system.web>
  <system.webServer>
<handlers><add  verb="*" path="*.SampleAsync"name="HelloWorldAsyncHandler"type="HelloWorldAsyncHandler"modules="IsapiModule"/>scriptProcessor="%path%\aspnet_isapi.dll"</handlers>
  </system.webServer>
</configuration>

 

IIS 7.0 注册handler 集成模式下

 

<configuration>
  <system.webServer>
<handlers><add verb="*" path="*.SampleAsync"name="HelloWorldAsyncHandler"type="HelloWorldAsyncHandler"/></handlers>
  </system.webServer>
</configuration>

使用TPM的方式实现

<%@ WebHandler Language="C#" Class="ajaxResponse" %>

public class ajaxResponse: System.Web.HttpTaskAsyncHandler
{
	//設定一個集合來存放結果集
	private System.Collections.Generic.List<ORM_Class> oResult;
	//泛型處理常式主要進入點
	public override async System.Threading.Tasks.Task ProcessRequestAsync(System.Web.HttpContext context)
	{
		//指定要存取的網址,壓入非同步工作中
		await PushToTask(new string[] {
			"http://date.jsontest.com",	//FreeJson
			"http://date.jsontest.com",	//FreeJson
			"http://date.jsontest.com"	//FreeJson
		});
		//輸出結果集之JSON
		context.Response.ContentType = "application/json; charset=utf-8";
		context.Response.Write(Newtonsoft.Json.JsonConvert.SerializeObject(oResult));
	}

	//非同步工作佇列處理
	private async System.Threading.Tasks.Task PushToTask(System.Collections.Generic.IList<string> oURLs)
	{
		System.Collections.Generic.List<System.Threading.Tasks.Task> oTasks = new System.Collections.Generic.List<System.Threading.Tasks.Task>();
		System.Threading.SemaphoreSlim oControl = new System.Threading.SemaphoreSlim(oURLs.Count);
		oResult = new System.Collections.Generic.List<ORM_Class>();
		foreach (var cURL in oURLs)
		{
			await oControl.WaitAsync();
			oTasks.Add(System.Threading.Tasks.Task.Run(async () =>
			{
				try
				{
					using (System.Net.WebClient oWC = new System.Net.WebClient() { Encoding = System.Text.Encoding.UTF8 })
					{
						oResult.Add(Newtonsoft.Json.JsonConvert.DeserializeObject<ORM_Class>(
							await oWC.DownloadStringTaskAsync(new System.Uri(cURL))
						));
					}
				}
				catch { return; }
				finally { oControl.Release(); }
			}));
		}
		//等候所有的工作完成
		await System.Threading.Tasks.Task.WhenAll(oTasks);
	}
}

//預計取用的ORM類別
class ORM_Class
{
	public string time { get; set; }
	public long milliseconds_since_epoch { get; set; }
	public string date { get; set; }
}

 

参考

Walkthrough: Creating an Asynchronous HTTP Handler
在泛型處理常式(ashx)中利用HttpTaskAsyncHandler來完成async/await之需求
posted @ 2016-07-20 16:15  霍旭东  阅读(1012)  评论(0编辑  收藏  举报