簡體   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