在高并发下的服务器端编程,当遇到性能瓶颈时候,往往是同步带来的。监听HTTP请求的时候,异步是必须的。
异步监听HTTP请求的基类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Web;
namespace MyHandler
{
public abstract class HttpAsyncHandler : IHttpAsyncHandler, IAsyncResult
{
public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
{
_callback = cb;
_context = context;
_completed = false;
_state = this;
ThreadPool.QueueUserWorkItem(new WaitCallback(DoProcess), this);
return this;
}
public void EndProcessRequest(IAsyncResult result)
{
}
public bool IsReusable
{
get { return false; }
}
public abstract void BeginProcess(HttpContext context);
public void EndProcess()
{
//防止多次进行多次EndProcess
if (!_completed)
{
try
{
_completed = true;
if (_callback != null)
{
_callback(this);
}
}
catch (Exception) { }
}
}
private static void DoProcess(object state)
{
HttpAsyncHandler handler = (HttpAsyncHandler)state;
handler.BeginProcess(handler._context);
}
public void ProcessRequest(HttpContext context)
{
throw new NotImplementedException();
}
private bool _completed;
private Object _state;
private AsyncCallback _callback;
private HttpContext _context;
public object AsyncState
{
get { return _state; }
}
public WaitHandle AsyncWaitHandle
{
get { throw new NotImplementedException(); }
}
public bool CompletedSynchronously
{
get { return false; }
}
public bool IsCompleted
{
get { return _completed; }
}
}
}
添加TestHandler.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace MyHandler
{
public class TestHandler : HttpAsyncHandler
{
public override void BeginProcess(System.Web.HttpContext context)
{
try
{
StreamReader sr = new StreamReader(context.Request.InputStream);
string reqStr = sr.ReadToEnd();
context.Response.Write("get your input : " + reqStr + " at " + DateTime.Now.ToString());
}
catch (Exception ex)
{
context.Response.Write("exception eccurs ex info : " + ex.Message);
}
finally
{
EndProcess();最后别忘了end
}
}
}
}
在站点引入MyHandler.dll,并按照如下修改 WebConfig:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0"/>
<pages validateRequest="false" controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID"/>
<httpRuntime requestValidationMode="2.0"/>
<customErrors mode="Off"/>
<httpHandlers>
<add verb="*" path="Test.aspx" type="MyHandler.TestHandler, MyHandler"/>
</httpHandlers>
</system.web>
</configuration>