获取线程的状态
本文关键字:状态 线程 获取 | 更新日期: 2023-09-27 17:52:44
我正在运行一个发送邮件的线程。我怎么知道一个线程已经完成了它的执行?
new Thread(x => SendMail(node.Attributes["id"].Value.ToString(), node["fname"].InnerText + " " + node["lname"].InnerText, 500, node["email"].InnerText)).Start();
var thr = new Thread(x => SendMail(node.Attributes["id"].Value.ToString(), node["fname"].InnerText + " " + node["lname"].InnerText, 500, node["email"].InnerText));
thr.Start();
thr.Join();//In this place main thread will wait
您应该保留对您创建的线程实例的引用,然后检查ThreadState
。您还可以检查IsAlive
属性,以查看线程当前是否正在执行。
这取决于您的环境。例如,您可以通过使用Tasks并订阅continuation来避免使用所有线程。
。
var task = Task.Run(DoSomething)
.ContinueWith(a => Whatever())
或者使用c# 5提供的方便关键字:
var task = await Task.Run(DoSomething);
Whatever();
如果你必须使用线程,我建议传递一个委托,当电子邮件完成后,你只需要调用它:
// Outside the thread
private Action callback;
// Before starting the thread
callback = MyMethod/*Or a lambda if you want*/;
// In the thread action
Action<object> threadBody = x =>
{
SendMail(node.Attributes["id"].Value.ToString(), node["fname"].InnerText + " " + node["lname"].InnerText, 500, node["email"].InnerText);
callback();
};
另一种变化是将ThreadPool.QueueUserWorkItem
与ManualResetEvent
结合使用:
:
private void DoWork()
{
List<ManualResetEvent> events = new List<ManualResetEvent>();
//in case you need to loop through multiple email addresses
//use the foreach here, assuming that the items is a list.
//foreach(var item in items)
//{
var resetEvent = new ManualResetEvent(false);
ThreadPool.QueueUserWorkItem(arg =>
{
SendMail(node.Attributes["id"].Value.ToString(),
node["fname"].InnerText + " " + node["lname"].InnerText,
500, node["email"].InnerText);
resetEvent.Set();
});
events.Add(resetEvent);
//} <- closes the foreach loop
//WaitHandle.WaitAll waits for all the threads to finish.
WaitHandle.WaitAll(events.ToArray());
MessageBox.Show("Mails are sent", "Notification");
}
如果您想循环遍历电子邮件地址列表或数组,并为每个邮件单独启动一个线程,这将特别有用。
在您的情况下,如果您想在等待邮件发送时做其他事情。您可以简单地在后台线程中运行上面的代码,当消息显示时,您就知道工作完成了。
public void StartMailThread()
{
Thread myThread = new Thread(DoWork)
{
IsBackground = true,
Name = "MailThread"
};
myThread.Start();
}
虽然,用一个线程来启动一个线程池对我来说似乎有点奇怪。
除了Andrew的答案,你可以使用BackgroundWorker,它已经有RunWorkerCompleted事件BackgroundWorker