これが基本的なセットアップです。外部 Web サービスにアクセスする必要がある Flash アプリケーションを含むページを持つ ASP.Net WebForms アプリケーションがあります。Flash の (おそらくセキュリティ上の) 制限により (質問しないでください。私は Flash の専門家ではありません)、Flash から Web サービスに直接接続することはできません。回避策は、Flash アプリケーションが呼び出すプロキシを ASP.Net で作成することです。これにより、WebService が呼び出され、結果が Flash アプリケーションに転送されます。
ただし、Web サイトのトラフィックは非常に多く、問題は、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 を活用できる方法があるかどうか、または他の何かがあるかどうか疑問に思っています。どんなフィードバックでも大歓迎です。ありがとう!!