アプリケーションが統合モードで実行されている場合、ホスト環境内でメール ディスパッチャ サービスを登録できます。ホストは、リサイクルが完了する前にサービスに通知します。ホストは実装をIRegisteredObject.Stop
正確に 2 回呼び出します。最初の電話で、ホストはあなたに仕事を終わらせる機会を与えます。タイムアウトに達し、サービスがホストから削除されていない場合、別の呼び出しが行われますが、今回はサービスの同意の有無にかかわらずリサイクルが行われることを通知するためだけです。
これは、Stop() メソッドを実装する方法の例 (テストされていません) です。
public class MailDispatchService : IRegisteredObject
{
private AutoResetEvent _processQueueEvt = new AutoResetEvent();
private ConcurrentQueue<MailMessage> _queue = new ConcurrentQueue<MailMessage>();
private Thread _dispatcherThread;
private volatile bool _enabled = true;
#region Implementation of IRegisteredObject
public void Stop(bool immediate)
{
if (_dispatcherThread != null && _dispatcherThread.IsAlive)
{
// it's not an immediate stop, we can wait for the queue to empty
if (!immediate)
{
// stop accepting new items in the send queue...
_enabled = false;
// awake dispatcher thread, so it can quit if the queue is empty
_processQueueEvt.Set();
// and wait for a while but not forever.
_dispatcherThread.Join(TimeSpan.FromSeconds(30));
}
else
{
// host env will recycle now, nothing to do...
_dispatcherThread.Abort();
}
}
// remove the service from host
HostingEnvironment.UnregisterObject(this);
}
#endregion
public void Start()
{
_dispatcherThread = new Thread(ProcessQueue);
_dispatcherThread.Start();
}
private void ProcessQueue()
{
while (_enabled)
{
_processQueueEvt.WaitOne();
MailMessage message;
while (_queue.TryDequeue(out message)) { /* send mail ...*/}
}
}
public void DispatchEmail(MailMessage message)
{
if (!_enabled) throw new Exception("....");
_queue.Enqueue(message);
_processQueueEvt.Set();
}
}
サービスを開始し、ホストに登録します。
var mailService = new MailDispatchService();
System.Web.Hosting.HostingEnvironment.RegisterObject(mailService);
mailService.Start();
var message = new MailMessage();
mailService.DispatchEmail(message);