耗时很长的服务器端事件中让客户端得到中间过程信息的更合理的解决方案
readStart_SendMailMessageCache()
{
while (true)
{
if (ExitAllDaemonThreads) return;
IList<MailMessageHolder> hl = this.MailMessageCache.FindNeedToSendMessageHolders(MailMessageCache.GetAllMessage());
if (hl == null || hl.Count == 0)
{
lock (SendMailMessageCacheThreadSyncRoot)
{
Monitor.Wait(SendMailMessageCacheThreadSyncRoot);
continue;
}
}
else
{
foreach (MailMessageHolder h in hl)
{
if (ExitAllDaemonThreads) return;
if (h.SendExpired) continue;
if (!h.SendOk)
{
try
{
SendMail(h);
Thread.Sleep(1000);
}
catch (SmtpException se)
{
h.ErrorMessage = se.StatusCode.ToString();
}
}
}
}
Thread.Sleep(30000);
}
}
当有新发送任务时先将任务批量添加到MessageCache,然后Monitor.PulseAll(SendMailMessageCacheThreadSyncRoot)一下。如果觉得后台线程太多不好的话,也可以没 有任务时中止线程,有任务时再启动。 这种解决方案的好处非常明显: (1)无论是B/S程序还是C/S程序还是控制台程序都使用,换个UI非常简单 (2)查看发送进度: MessageCache<TMessageHolder>.GetAllMessage(),搞个GridView显示下就行了,可以看具体的发送信息。也可以计算统计信息,都挺简单的。 (3)具备发送失败自动重发功能 (4)用户可以同时提交多个发送任务 (5)用个持久化方案就可以实现断点重发。B/S用数据库,C/S用文件或数据库 (6)与Session无关 (7)后台非常柔性。你可以写一个线程处理多个MessageCache,也可以多个线程处理多个MessageCache,也可以多个线程处理一个MessageCache,也可以采用异步方式 处理,也可以多线程+异步,也可以用协程调度,也可以用event-dispatch-scheduler方式处理,也可以存在数据库让几台机器一起发,也可以像TCP协议那样加入拥塞控制 机制。总之根据需求与服务器的负载情况来。 这种解决方案适用面很广,比如,我写的B/S式的Spider,可以多个用户同时登陆使用,每个用户可以有多任务,而我还想对用户进行区分,比如会员可以爬行快点,一 般的慢点,会员爬的层次多,一般的爬的少,采用的就是类似的方案,不过后台线程调度复杂一点(其实也复杂不了多少)。 只提供思路,不提供具体源码。 |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |