カスタムキャッシュに約25〜30個のアイテム(ユーザーがフォームからフォローアップリクエストを行うときに必要な情報があります)を書き込むasp.net Webフォームがあります。現在、これはすべてメイン スレッドで同期的に行われます。しかし、負荷が高くなると addcache がボトルネックになります。
asp.net ワーカー プロセス スレッド プールからスレッドを消費せずに、このタスクをバックグラウンドで実行するにはどうすればよいですか。
カスタムキャッシュに約25〜30個のアイテム(ユーザーがフォームからフォローアップリクエストを行うときに必要な情報があります)を書き込むasp.net Webフォームがあります。現在、これはすべてメイン スレッドで同期的に行われます。しかし、負荷が高くなると addcache がボトルネックになります。
asp.net ワーカー プロセス スレッド プールからスレッドを消費せずに、このタスクをバックグラウンドで実行するにはどうすればよいですか。
代替案:
クライアントから AJAX を使用してサーバー コードを呼び出し、呼び出しのプロセスを監視するコードを追加します。
このプロセスに関連する回答を追加しました。
クライアントからサーバーへの呼び出しは同期されます。つまり、プロセス全体が終了するまで応答はクライアントに返されませんが、実際のコードは非同期で実行され、ASP.Net によって使用されるスレッドが解放され、スケーラビリティが向上します。
ページを非同期で実行します。IHttpAsyncHandler
ASPX コード ビハインドでインターフェイスを実装する必要があります。これは例です:
public partial class _Default : System.Web.UI.Page, IHttpAsyncHandler
{
public void EndProcessRequest(IAsyncResult result)
{
var context = (result as AsyncOperation).Context;
context.Response.Write(string.Format("<p>End Process Request on {0}</p>", Thread.CurrentThread.ManagedThreadId.ToString()));
}
public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
{
var operation = new AsyncOperation(cb, this.Context, extraData);
operation.StartAsync();
this.Context.Response.Write(string.Format("<p>Begin Process Request on: {0}...</p>", Thread.CurrentThread.ManagedThreadId.ToString()));
return operation;
}
}
public class AsyncOperation : IAsyncResult
{
private AsyncCallback asyncCallback;
public AsyncOperation(AsyncCallback asyncCallback, HttpContext context, object state)
{
this.AsyncState = state;
this.asyncCallback = asyncCallback;
this.Context = context;
this.IsCompleted = false;
this.AsyncWaitHandle = null;
this.CompletedSynchronously = false;
}
public HttpContext Context { get; private set; }
public object AsyncState { get; private set; }
public WaitHandle AsyncWaitHandle { get; private set; }
public bool CompletedSynchronously { get; private set; }
public bool IsCompleted { get; private set; }
public void StartAsync()
{
ThreadPool.QueueUserWorkItem(new WaitCallback(StartAsyncOperation), this.AsyncState);
}
public void StartAsyncOperation(object workItemState)
{
// place here the async logic
this.Context.Response.Write(string.Format("<p>Long Async operation started on: {0}</p>", Thread.CurrentThread.ManagedThreadId.ToString()));
Thread.Sleep(2000);
this.Context.Response.Write(string.Format("<p>Long Async operation ended on: {0}</p>", Thread.CurrentThread.ManagedThreadId.ToString()));
this.IsCompleted = true;
this.asyncCallback(this);
}
}
出力
HttpAsyncHandler を作成します。HttpHandler
インターフェイスを実装するカスタムを作成する必要がありIHttpAsyncHandler
ます。例:
public class AsyncHandler : IHttpAsyncHandler
{
public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
{
var operation = new AsyncOperation(cb, context, extraData);
operation.StartAsync();
context.Response.Write(string.Format("<p>Begin Process Request on: {0}...</p>", Thread.CurrentThread.ManagedThreadId.ToString()));
return operation;
}
public void EndProcessRequest(IAsyncResult result)
{
var context = (result as AsyncOperation).Context;
context.Response.Write(string.Format("<p>End Process Request on {0}</p>", Thread.CurrentThread.ManagedThreadId.ToString()));
}
public bool IsReusable
{
get { return false; }
}
public void ProcessRequest(HttpContext context)
{
throw new NotImplementedException();
}
}