繁体   English   中英

c#中foreach循环内的线程

[英]Threads inside a foreach loop in c#

海家伙,

我有以下代码将不同的邮件发送到我的asp.net Web应用程序中的不同用户

foreach (DataRow dataRow in dataTable.Rows) 
{
   sendMails();
}
public void sendMails()
{
 //mail code
}

现在我想在foreach循环中使用线程,但我不知道结果是什么,因为如果我开始'n'线程池中发生什么线程...考虑我的数据表包含1000行,

是否可以同时运行1000个线程?

foreach (DataRow dataRow in dataTable.Rows) 
{
    ThreadStart ts1 = new ThreadStart(sendMails);
    Thread thread1 = new Thread(ts1);
    thread1.Start();
}

public void sendMails()
{
   //mail code
}

启动一个可以完成发送所有邮件的线程:

new Thread(() => {
    foreach (DataRow dataRow in dataTable.Rows) 
    {
        sendMails();
    }
}).Start();

使用你已经获得的代码,线程池不会发生任何事情 - 你将在线程池之外完全创建新线程。

您确定要为每封邮件使用一个帖子 - 甚至是多个线程吗? 我想你会受到与本地SMTP服务器连接的限制,启动多个线程对你没有帮助。

如果使用线程的目的是能够将页面返回给用户说“是的,我现在正在发送邮件”,那么启动单个线程在后台发送所有内容(根据Darin的建议)更为明智。 另一方面,它确实意味着如果该过程因任何原因而停止,您最终可能只发送了一半。 另一种选择(如Charlie所建议的)是使用排队系统(例如文件,数据库或MSMQ)。 这样你就可以阻止,直到你排队所有的邮件,这意味着当你回到用户时你可以确信数据是“安全的” - 但是你可以在后台发送实际的邮件,并提供可能的服务。更健壮。

看一下使用带有单独Windows服务的消息队列来发送电子邮件会不会更明智?

不要创建自己的线程,拥有1000个线程意味着CPU花费所有时间在它们之间切换,而实际执行任何工作的时间都很少。

使用线程池执行此操作,它将执行最多25个(默认情况下)后台线程,并且可以在它们全部忙碌时自动阻止。

请参阅MSDN教程

使用线程池可能更为明智,甚至是.NET 4.0(或并行FX)中的Parallel Linq:

dataTable.Rows.AsParallel().Select(a =>
{
    //mail code
    return null;
});

每个电子邮件的线程不是最好的想法,正如许多人所解释的那样,但是如果您决定创建一个后台线程来处理所有电子邮件,则线程运行时间将限制为110秒。 ASP.NET在.NET 2.0中默认将线程执行限制为110秒。 http://msdn.microsoft.com/en-us/library/e1f13641(v=vs.80).aspx

创建队列 - 正如其他人在之前的回复中所建议的那样 - 更加合理和可扩展。

http://msdn.microsoft.com/en-us/library/system.web.configuration.httpruntimesection.executiontimeout.aspx

构建你的方法可能会更好:

public void SendMails(DataTable dt)
{
    foreach (DataRow row in dt.Rows)
    {
        // send emails
    }
}

然后像这样调用它:

SendMails(dataTable);

或者使用BackgroundWorker调用该方法,以便您的UI不会锁定。

第一点是,如果您显式创建这样的线程,则不使用线程池。 CLR将通过创建所有这些线程来实现,即使它最终会创建太多并且拖延自己。 1000个明确的主题是太多

您是否尝试在另一个线程上执行此操作,因为您希望它以异步方式发生,或者您实际上是否希望多个线程执行发送?

如果是前者,那么尝试类似:

ThreadStart ts1 = new ThreadStart(sendMails);
Thread thread1 = new Thread(ts1);
thread1.Start();

public void sendMails()
{
   foreach (DataRow dataRow in dataTable.Rows) 
   {
      //mail code
   }
}

如果您确实认为某些多线程会改善发送性能,那么您需要手动限制一次创建的线程数,或者使用.Net线程池,因为这样可以排队工作项将阻塞直到线程变为空闲。 这当然比创建显式线程的负载更可取。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM