解决:我找到了解决方案.不知道为什么会发生这种情况但是将“应用程序池类型”从“集成”切换为“经典”可以解决问题.现在’Requests Executing’继续上升,实际的应用程序池进程线程仍然很低(~31个线程),并且应用程序响应非常快(应该如此).
我正在使用.Net 2.0所以也许有一个问题 – 尝试google但没有运气.
我正在使用.Net 2.0所以也许有一个问题 – 尝试google但没有运气.
见Joe Enzminger’s reply for an explanation
再次感谢大家.
PS.该代码用于在线播放池(台球) – windows(免费)版本here为任何好奇和勇敢的人尝试:)
你好,
我已经实现了一个IHttpAsyncHandler,客户端应用程序“轮询”等待服务器通知.通知由服务器上的其他“活动”生成,而异步处理程序根本不起作用.
执行步骤是:
IHttpAsyncHandler.BeginProcessRequest Create AsyncResult instance and add it to a "registered clients" collection return the AsyncResult
AsyncResult.CompleteCall called as a result of the generated notification(s). IHttpAsyncHandler.EndProcessRequest is called The notification(s) attached to the AsyncResult are written to the response stream.
问题:
我已经在具有Windows Server 2008 SP2和1个cpu核心的VM上的IIS7上测试了这个.在12个客户端注册通知(使用Async.ashx上的HTTP GET)后,性能降低到后续客户端无法连接的程度.
当我检查ASP.NET性能计数器时,“Requests Executing”计数器随每个客户端注册而上升并保持在12(这似乎是它的最大值 – 可能是每个cpu的线程池大小).
我觉得这很令人困惑.我虽然异步处理程序的重点是为其他连接释放线程.看来情况并非如此,所以我一定做错了!
为什么ASP.NET在等待我的AsyncResult完成时消耗一个线程?这是配置问题吗?我是否需要做一些特定的事情来表明这是一个异步处理程序?
谢谢,
尼科斯.
public class AsyncResult : IAsyncResult { private AsyncCallback _cb; private object _state; private ManualResetEvent _event; private bool _completed; private bool _completedsynchronously; private HttpContext _context; private byte[] _data; private int _datalength; private object _lock = new object(); public AsyncWaitResult(AsyncCallback cb,object state,HttpContext context) { _context = context; _cb = cb; _state = state; } public void Close() { if (_event != null) { _event.Close(); _event = null; } } public HttpContext Context { get { return _context; } } public Object AsyncState { get { return _state; } } public bool CompletedSynchronously { get { return _completedsynchronously; } } public bool IsCompleted { get { return _completed; } } public byte[] Data { get { return _data; } } public int DataLength { get { return _datalength; } } public WaitHandle AsyncWaitHandle { get { lock (_lock) { if (_event == null) _event = new ManualResetEvent(_completed); return _event; } } } public void CompleteCall(byte[] data,int length,bool completedsynchronously) { _data = data; _datalength = length; _completedsynchronously = completedsynchronously; lock (_lock) { _completed = true; if (_event != null) _event.Set(); } if (_cb != null) _cb(this); } } public class Outbound : IHttpAsyncHandler { public IAsyncResult BeginProcessRequest(HttpContext context,AsyncCallback cb,object state) { AsyncResult asyncresult = new AsyncResult(cb,state,context); RegisteredClients.Instance.Add(asyncresult); return asyncresult; } public void EndProcessRequest(IAsyncResult ar) { AsyncResult result = (AsyncResult)ar; if (result != null) { result.Context.Response.Cache.SetCacheability(HttpCacheability.NoCache); result.Context.Response.ContentType = "application/octet-stream"; result.Context.Response.AddHeader("Connection","keep-alive"); if (result.Data != null) result.Context.Response.OutputStream.Write(result.Data,result.DataLength); result.Close(); } } public void ProcessRequest(HttpContext context){} public bool IsReusable { get { return true; } } }