【发布时间】:2015-07-06 05:13:20
【问题描述】:
我有一个 Windows 服务,它在经过漫长的过程后发送电子邮件。 只要有表条目,该服务就会继续从数据库表中获取电子邮件数据并对其进行处理并将其发送出去。
目前它是一个多线程应用程序,我们在生产服务器中配置线程数最多为 25(仅用于此目的),因为这意味着运行 24x7x365 。但是我们看到只有 2 个活动线程在运行。可能是什么原因?
我还希望在这里使用线程池或 TPL 更改线程代码。您能否建议我一种更好的方法来处理这种情况?
提前致谢!
//下面的示例代码
Thread[] threads;
int ThreadCount = 25;
private void StartProcess()
{
//Create new threads
if (Threads == null)
{
// Create array of threads based on the configuration
threads = new Thread[ThreadCount];
for (int i = 0; i < ThreadCount; i++)
{
Thread[] threads[i] = new Thread(new ThreadStart(SendEmail));
threads[i].Start();
}
}
else
{
resume it if exists
for (int j = 0; j < threads.Length; j++)
{
if (threads[j].ThreadState == Threading.ThreadState.Suspended)
{
threads[j].Resume();
}
}
}
}
public void SendEmail()
{
while (Thread.CurrentThread.ThreadState == System.Threading.ThreadState.Running)
{
// send email code
Thread.Sleep(duration);
}
}
【问题讨论】:
-
你做了大量的 IO 工作,我看不出有任何理由使用 25 个线程。查看
SmtpClient.SendMailAsync和异步数据库端点。 -
TPL 正在使用线程池。许多类将异步方法公开为任务,因此没有理由使用原始线程
-
请注意 Thread.Suspend 不适合生产。如果它碰巧暂停了 string 的静态构造函数,那么你的进程就会被冲洗掉。你需要把它扔掉。
-
实际上,您要解决什么问题?您有要发送的邮件队列吗?为什么不直接在 BlockingCollection 上使用 Parallel.ForEach?扔掉所有这些代码。
-
ActionBlock
是另一个不错的选择 - 负责排队消息,通过简单的配置允许并发执行。
标签: .net multithreading task-parallel-library threadpool c#-5.0