[英]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
創建隊列 - 正如其他人在之前的回復中所建議的那樣 - 更加合理和可擴展。
構建你的方法可能會更好:
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.