在循环中创建新线程,是初学者常犯的错误。下面给出一段示例代码,注意:运行它们可能导致系统不可使用。除非不介意重启,否则最好别运行它们。
- using System;
- using System.Web.Mail;
- using System.Threading;
- using System.Collections;
- public class LoopingThreads
- {
- public delegate void SendMail(string oMessageTo);
- private class MyMail
- {
- public string EmailTo;
- public string EmailFrom;
- public String EmailSubject;
- public string EmailBody;
- public SendMail SendThisMail; //delegate instance
- public void Send()
- {
- System.Web.Mail.MailMessage oMail = new System.Web.Mail.MailMessage();
- oMail.To = EmailTo;
- oMail.From = EmailFrom;
- oMail.Body = EmailBody;
- oMail.Subject = EmailSubject;
- SmtpMail.Send(oMail);
- SendThisMail(EmailTo);
- }
- }
- public static Thread CreateEmail(SendMail oSendEmail, string EmailTo, string EmailFrom, string EmailBody, string EmailSubject)
- {
- MyMail oMail = new MyMail();
- oMail.EmailFrom = EmailFrom;
- oMail.EmailBody = EmailBody;
- oMail.EmailSubject = EmailSubject;
- oMail.EmailTo = EmailTo;
- oMail.SendThisMail = oSendEmail;
- Thread t = new Thread(new ThreadStart(oMail.Send));
- return t;
- }
- }
- class Mailer
- {
- public static void MailMethod(string oString)
- {
- Console.WriteLine("Sending Email:" + oString);
- }
- }
- public class DoMail
- {
- static ArrayList al = new ArrayList();
- public static void Main()
- {
- for (int i = 1; i <= 1000; i++)
- {
- al.Add(i.ToString() + "@somplace.com");
- }
- SendAllEmail();
- }
- public static void SendAllEmail()
- {
- int loopTo = al.Count - 1;
- for (int i = 0; i <= loopTo; i++)
- {
- Thread t = LoopingThreads.CreateEmail(new LoopingThreads.SendMail(Mailer.MailMethod), (string)al[i], "johndoe@somewhere.com", "Threading in a loop", "Mail Example");
- t.Start();
- t.Join(Timeout.Infinite);
- }
- }
- }
为什么不在另一个线程上发送Email呢?它有时需要很长时间来处理,不是吗?是的,但问题是在线程之间来回切换将占用处理器的执行时间。到完成这个进程为止,分配到每个线程的时间片主要花费在拆包和打包线程本地存储上了。执行线程中的指令只花费了很少的时间。系统可能会完全锁住,无法发送Email。更合理的解决方案是创建一个线程,并在该线程上执行SendAllEmail方法。另外,再使用一个含有固定数目线程的线程池。在这个实例中,当线程池中的一个线程完成后,它将产生下一个线程,发送另一封Email。
[1] 在编写程序的时候,提示错误:命名空间“System.Web”中不存在类型或命名空间名称“Mail”(是缺少程序集引用吗?)
解决方法:右键解决方案资源管理器中的“引用”->添加引用->System.Web.dll,添加即可。