在ASP.NET WebService中启动一个线程

3

我有一个托管在IIS上的WCF Web服务。

它有一个方法(我们称之为“ConfirmOrder”)。当调用此方法时,我想要做以下事情: 1. 快速更新数据库,生成OrderId。 2. 启动一个新线程进行一些慢工作(例如生成电子邮件并发送)。 3. 同步将步骤1中的OrderId返回给客户端。 4. 最终,在2中创建的新线程会完成所有其他处理并发送电子邮件。

问题:

(1) 我曾经有这样的代码:

// do printing and other tasks 
OrderConfirmedThreadHelper helper = new OrderConfirmedThreadHelper(userSession, result);
// some things first (like generating barcodes) in this thread 
Logger.Write(basket.SessionId, String.Format("Before ConfirmOrderSync"), LogCategoryEnum.Sales, System.Diagnostics.TraceEventType.Verbose);
helper.ConfirmOrderSync();
Logger.Write(basket.SessionId, String.Format("After ConfirmOrderSync"), LogCategoryEnum.Sales, System.Diagnostics.TraceEventType.Verbose);
// slower things (like rendering, sending email) in a separate thread
Thread helperThread = new Thread(new ThreadStart(helper.ConfirmOrderAsync));
helperThread.Start();
return result;

但是似乎出现了问题;至少,服务一直锁死。这样做是不好的吗?

(2) 我尝试将其更改为

// slower things (like rendering, sending email) in a separate thread            
ThreadPool.QueueUserWorkItem(new WaitCallback(helper.ConfirmOrderAsync));

但是线程池的线程似乎在主线程完成后立即被终止,因为它是一个后台线程。有没有更好的方法解决这个问题 - 除了编写一个全新的 Windows 服务进行通信?
1个回答

0
如果第二个线程在请求线程(来自浏览器的线程)之后完成,那么你就会遇到问题,因为它将被运行时回收并终止。如果你可以等待(如果只是发送电子邮件,可能需要几秒钟),你可以使用ManualResetEvent来同步一个线程等待另一个线程完成并优雅地清理。
如果你不能等待,在这种情况下,邮件处理的最佳选择是以下之一:
  1. Windows服务。
  2. 一个.ashx文件,您可以从客户端代码调用它,并通过jquery ajax调用传递发送邮件所需的数据。
  3. 批处理作业(计划任务、SQL Server作业等),从数据库中读取待发送的邮件并发送它们。它将每隔X分钟运行一次,因此您不必担心
希望这有所帮助!

我想我会选择使用Sql Server Service Broker,利用SqlSependency类来通知Windows服务,当记录被插入到数据库中并需要处理时。 - Ben Curthoys
实际上,我改变了主意。我将需要完成的内容写入数据库,然后发送一个XMPP消息到一个Windows服务,由该服务来完成它。 - Ben Curthoys

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接