【发布时间】:2011-06-18 01:15:47
【问题描述】:
这是基本设置。我们有一个 ASP.Net WebForms 应用程序,其页面包含一个需要访问外部 Web 服务的 Flash 应用程序。由于 Flash 的(我认为是安全的)限制(别问我,我根本不是 Flash 专家),我们不能直接从 Flash 连接到 Web 服务。解决方法是在 ASP.Net 中创建一个 Flash 应用程序将调用的代理,该代理将依次调用 WebService 并将结果转发回 Flash 应用程序。
虽然网站的流量非常高,但问题是,如果 Web 服务完全挂起,那么 ASP.Net 请求线程将开始备份,这可能导致严重的线程饥饿。为了解决这个问题,我决定使用专门为此目的设计的IHttpAsyncHandler。在其中,我将使用 WebClient 异步调用 Web 服务并将响应转发回来。网上关于如何正确使用 IHttpAsyncHandler 的示例很少,所以我只是想确保我没有做错。我的使用基于此处显示的示例:http://msdn.microsoft.com/en-us/library/ms227433.aspx
这是我的代码:
internal class AsynchOperation : IAsyncResult
{
private bool _completed;
private Object _state;
private AsyncCallback _callback;
private readonly 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()
{
using (var client = new WebClient())
{
var url = "url_web_service_url";
client.DownloadDataCompleted += (o, e) =>
{
if (!e.Cancelled && e.Error == null)
{
_context.Response.ContentType = "text/xml";
_context.Response.OutputStream.Write(e.Result, 0, e.Result.Length);
}
_completed = true;
_callback(this);
};
client.DownloadDataAsync(new Uri(url));
}
}
}
public class MyAsyncHandler : IHttpAsyncHandler
{
public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
{
var asynch = new AsynchOperation(cb, context, extraData);
asynch.StartAsyncWork();
return asynch;
}
public void EndProcessRequest(IAsyncResult result)
{
}
public bool IsReusable
{
get { return false; }
}
public void ProcessRequest(HttpContext context)
{
}
}
现在这一切都有效,我认为它应该可以解决问题,但我不能 100% 确定。另外,创建我自己的 IAsyncResult 似乎有点矫枉过正,我只是想知道是否有一种方法可以利用从 Delegate.BeginInvoke 返回的 IAsyncResult,或者其他方法。欢迎任何反馈。谢谢!!
【问题讨论】:
标签: c# .net asp.net asynchronous ihttpasynchandler