2012-10-01 58 views
1

所以即時嘗試推遲從我的程序發送電子郵件。 爲了保持UI的交互性,我開始了一個新線程,並在線程中調用了email方法。有用。它發送電子郵件。但我不知道如何睡覺的線程。 我試着在實際的電子郵件方法中使用Thread.sleep(),但它似乎沒有工作。睡覺一個新的線程c#

Thread oThread = new Thread(new ThreadStart(() => { sendEMailThroughOUTLOOK(recipientAddress, subjectLine, finalbody); })); 
       oThread.Start(); 

電子郵件方式..

public void sendEMailThroughOUTLOOK(string recipient, string subject, string body) 
    { 
     Thread.Sleep(60000); 

     try 
     { 

      // Create the Outlook application. 
      Outlook.Application oApp = new Outlook.Application(); 
      // Create a new mail item. 
      Outlook.MailItem oMsg = (Outlook.MailItem)oApp.CreateItem(Outlook.OlItemType.olMailItem); 
      // Set HTMLBody. 
      //add the body of the email 
      oMsg.Body = body; 

      oMsg.Subject = subject; 
      // Add a recipient. 
      Outlook.Recipients oRecips = (Outlook.Recipients)oMsg.Recipients; 
      // Change the recipient in the next line if necessary. 
      Outlook.Recipient oRecip = (Outlook.Recipient)oRecips.Add(recipient); 
      oRecip.Resolve(); 
      // Send. 
      oMsg.Send(); 
      // Clean up. 
      oRecip = null; 
      oRecips = null; 
      oMsg = null; 
      oApp = null; 



     }//end of try block 
     catch (Exception ex) 
     { 
     }//end of catch 

     //end of Email Method 
    } 
+2

也許這是一個愚蠢的問題,但爲什麼你想要線程睡覺? –

+3

你有沒有看過使用計時器? –

+0

在調試器中逐步完成。我猜你可以自己找到這個問題。這是一項重要的學習技能。 – usr

回答

1

沒有什麼明顯錯你發佈的代碼。但是,thread.Suspend()是一個非常舊的API =自.NET 2.0以來它已被棄用/廢棄,因爲這樣做不安全。

靜態方法Thread.Sleep(N)肯定會將調用線程掛起N毫秒。

澄清;調用Thread.Sleep掛起調用線程,所以在你的示例代碼中,你有;

public void sendEMailThroughOUTLOOK(string recipient, string subject, string body) 
{ 
    Thread.Sleep(60000); 
    ... 
} 

對Thread.Sleep(60000)的調用掛起正在執行sendEMailThroughOUTLOOK方法的線程。因爲你似乎是在自己的線程中調用該方法,正如所證明的那樣;

Thread oThread = new Thread(new ThreadStart(() => { sendEMailThroughOUTLOOK(recipientAddress, subjectLine, finalbody); })); 
oThread.Start(); 

正確的線程應該被掛起。

有沒有辦法做這樣的事情;

Thread t = new Thread(); 
t.Start(); 
t.Sleep(60000); 

您可以啓動或殺死正在運行的線程,但不會休眠/掛起它。如上所述 - 此API已被棄用,因爲它不是實現線程同步的安全方式(請參閱http://msdn.microsoft.com/en-us/library/system.threading.thread.suspend%28v=vs.71%29.aspx以解釋爲什麼這不是一個好主意)。

+0

即時通訊使用visual studio 2012.我可以使用Thread.Sleep(),但我真正需要做的是oThread.sleep。 oThread是我用來發送電子郵件的線程,第一行代碼 – Stonep123

+0

是啊。我的意思是看代碼,將thread.sleep放入發送電子郵件的方法中,睡眠當前線程。因爲我在新線程中調用了這個方法......我認爲它會睡1分鐘......但電子郵件根本不會發送。我感到困惑 – Stonep123

+0

電子郵件不發送!=線程不睡覺。在休眠線上放一個斷點,在後一行放一個斷點。然後,你可以得到一個公平的想法,該線程正在睡60s。一旦你確認了,你可以繼續研究爲什麼電子郵件沒有發送。 –

0

由於您對編程有點新穎,我不會盡力解釋所有相關的細節,但我認爲很酷的是,您向我展示了一個與您的示例有關的新技巧,所以如果可以的話我想幫助您。

這不是只有這種方式來編碼,但我可以告訴你,這是一個合理的。它使用後臺工作組件在發送電子郵件時保持UI的響應。請注意使用後臺工作人員提供的事件DoWork和RunWorkerCompleted。這些事件的設置發生在設計師這就是爲什麼我zipped the solution up for you所以你可以看看整個事情(我這樣做與谷歌驅動器,這是我第一次嘗試做一個公共共享 - 如果鏈接打開爲你喜歡它爲我做,你會得到一個文件菜單,您可以從中選擇下載)。

我創建了一個內部私有類並將其傳遞給後臺工作者。我這樣做是因爲我不想從運行在不同線程中的代碼訪問我的UI組件中的數據。這並不總是會引起問題,但我認爲這是一個很好的做法。另外,如果我想稍後重構代碼,它會使它更容易從DoWork中取出這些行,並將它們放在其他地方,而不會大驚小怪。

在多線程編程的更普遍領域 - 這是一個多面的主題,你不需要馬上得到它。 This是我最喜歡的教程(這本書也很棒)。

using System; 
using System.ComponentModel; 
using System.Windows.Forms; 
using Outlook = Microsoft.Office.Interop.Outlook; 

namespace Emailer 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void SendButton_Click(object sender, EventArgs e) 
     { 
      this.sendEmailBackgroundWorker.RunWorkerAsync(new _Email 
      { 
       Recipient = this.recipientTextBox.Text, 
       Subject = this.subjectTextBox.Text, 
       Body = this.emailToSendTextBox.Text 
      }); 
     } 

     private class _Email 
     { 
      public string Body { get; set; } 
      public string Subject { get; set; } 
      public string Recipient { get; set; } 
     } 

     private void sendEmailBackgroundWorker_DoWork(object sender, DoWorkEventArgs e) 
     { 
      var email = (_Email)e.Argument; 

      try 
      { 
       Outlook.Application oApp = new Outlook.Application(); 
       Outlook.MailItem oMsg = (Microsoft.Office.Interop.Outlook.MailItem)oApp.CreateItem(Outlook.OlItemType.olMailItem); 
       oMsg.Body = email.Body; 
       oMsg.Subject = email.Subject; 
       Outlook.Recipients oRecips = (Outlook.Recipients)oMsg.Recipients; 
       Outlook.Recipient oRecip = (Outlook.Recipient)oRecips.Add(email.Recipient); 
       oRecip.Resolve(); 
       oMsg.Send(); 
       oRecip = null; 
       oRecips = null; 
       oMsg = null; 
       oApp = null; 
      } 
      catch (Exception ex) 
      { 
       e.Result = ex; 
      } 

      e.Result = true; 
     } 

     private void sendEmailBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
     { 
      string message; 

      if (e.Result is Exception) 
       message = "Error sending email: " + (e.Result as Exception).Message; 
      else if (e.Result is bool && (bool)e.Result) 
       message = "Email is sent"; 
      else 
       throw new Exception("Internal Error: not expecting " + e.Result.GetType().FullName); 

      MessageBox.Show(message); 
     } 
    } 
}