2014-03-31 10 views
0

問題描述: 我想創建一個新線程來發送一些電子郵件。執行:C#如何阻止線程,直到發送的電子郵件的所有響應都到達

Thread _thread = new Thread(new ThreadStart(StartSendingEmails)); 

調用的函數:

public void StartSendingEmails() 
     { 
      var engine = new SendGridEmailEngine(From, FromName) 
      { 
       TemplateUrl = _templateUrl, 
       QueryValues = _queryValues, 
       MailHeaders = _mailHeaders 
      }; 

      engine.SendEmail(EmailContent, Subject); 
     } 

和發送功能:

public void SendEmail(string emailContent, string subject) 
     { 
      int counter = 0; 
      LastResponseReceived = DateTime.Now; 

      foreach (var listItem in QueryValues) 
      { 
       //other operations.... 

       // 50 emails stack => wait... 
       while (counter - ReceivedResponses > 50) 
        Thread.Sleep(100); 

       //increase number of sent emails 
       counter++; 
       SendEmail(_from, _fromName); 
      } 

     //wait for all responses to be received 
     while (ReceivedResponses < QueryValues.Count && (DateTime.Now - LastResponseReceived).TotalMinutes <= 2) 
      Thread.Sleep(1000); 

     //force exit if more than 2 min left and not all the responses received 
     if (ReceivedResponses < QueryValues.Count && (DateTime.Now - LastResponseReceived).TotalMinutes >= 2) 
      WriteLog(string.Format("Forced exit!); 
} 

至極電話:

public void SendEmail(string from, string fromName) 
     { 
      //other operations 
      client.SendCompleted += new SendCompletedEventHandler(client_SendCompleted); 
     } 
void client_SendCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e) 
     { 
      ReceivedResponses++; 
      LastResponseReceived = DateTime.Now; 

      if (e.Error != null) 
      { 
      } 
      else 
      { 
       SentEmailsSuccessfully++; 
      } 
     } 

這裏是問題。所有電子郵件都會發送,但線程並未等待所有響應。有沒有辦法讓胎面比我用過的還要活?

//wait for all responses to be received 
    while (ReceivedResponses < QueryValues.Count && (DateTime.Now - LastResponseReceived).TotalMinutes <= 2) 
     Thread.Sleep(1000); 
+0

線程對於這個問題是一個非常昂貴的解決方案;有更好的方法來解決它。想想讓一個線程僱傭一名工人。你會僱用一名工人並支付他們睡覺,直到收到一封電子郵件? –

回答

2

您應該將每個完整的發送操作封裝到Task對象中。您可以awaitTask.WhenAll的結果等待所有任務完成。

List<Task> sendTasks = new List<Task>(); 

foreach (var listItem in QueryValues) 
{ 
    sendTasks.Add(SendEmailAsync(_from, _fromName); 
} 

// wait for all responses to be received 
await Task.WhenAll(sendTasks); 

提供取消操作的方法,如果時間過長,只需使用CancellationTokenSource一個超時。

using (var cts = new CancellationTokenSource(TimeSpan.FromMinutes(2))) 
{ 
    List<Task> sendTasks = new List<Task>(); 

    foreach (var listItem in QueryValues) 
    { 
    sendTasks.Add(SendEmailAsync(_from, _fromName, cts.Token); 
    } 

    // wait for all responses to be received 
    await Task.WhenAll(sendTasks.ToArray()).ConfigureAwait(false); 
} 
相關問題