如果您的应用程序以集成模式运行,您可以在主机环境中注册您的邮件调度程序服务。主机将在回收完成之前通知您的服务。主机将调用您的执行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);