2013-01-11 72 views
0

我正在运行正在发送邮件的线程。我怎么知道线程已经完成执行?获取线程状态

new Thread(x => SendMail(node.Attributes["id"].Value.ToString(), node["fname"].InnerText +  " " + node["lname"].InnerText, 500, node["email"].InnerText)).Start(); 
+7

?如果是这样,使用'任务'将是一个更好的主意IMO。 –

+0

您需要知道线程的状态或是否调用并退出'SendMail'方法? – sll

+0

在做其他工作时,我需要得到通知,说明该线程是否已完成执行,并向用户发出完成任务已完成的消息 – user1844205

回答

1

除了安德鲁的回答,您可以使用的BackgroundWorker它已经有您正在使用.NET 4 RunWorkerCompleted事件 BackgroundWorker

2

您应该保留对您创建的线程实例的引用,然后检查ThreadState。您还可以检查IsAlive属性以查看线程当前是否正在执行。

3
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 
2

这取决于你的环境是什么。例如,您可以通过使用任务并订阅延续来避免所有线程。

例如

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(); 
}; 
2

另一种变化是结合ManualResetEvent使用ThreadPool.QueueUserWorkItem

如:

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(); 
} 

尽管使用线程启动线程池似乎对我来说有点奇怪。