2012-03-07 39 views
0

@Title如何確定SmtpClient.send發送消息的時間?

如何確定它採取發送郵件的時間?

現在,當我點擊「發送」時,我的程序只是沉默。我希望程序能夠顯示類似進度條的東西,當程序正在發送消息時它將加載。

這可能嗎?

由於一時的,這是我有:

  try 
      { 
       MySqlDataAdapter adapter = new MySqlDataAdapter(); 
       MySqlCommand cmd = new MySqlCommand(getEmail, connect.connection); 
       cmd.Parameters.AddWithValue("@section", sectionSelect.SelectedValue); 

       adapter.SelectCommand = cmd; 

       System.Data.DataTable mailingList = new System.Data.DataTable(); 

       adapter.Fill(mailingList); 

       foreach (DataRow row in mailingList.Rows) 
       { 
        string rows = string.Format("{0}", row.ItemArray[0]); 
        message.To.Add(rows); 
       } 

       SmtpClient client = new SmtpClient(); 

       client.Credentials = new NetworkCredential(email, password.Password); 
       client.Host = "smtp.gmail.com"; 
       client.Port = 587; 
       client.EnableSsl = true; 

       client.Send(message); 
      } 
      catch (System.Exception ex) 
      { 
       MessageBox.Show(ex.ToString()); 
      } 

      finally 
      { 
       MessageBox.Show("Your message has been sent."); 
      } 
+0

進度條會浪費,因爲SmtpClient.Send不報告中間狀態。 – 2012-03-07 18:30:40

+0

太糟糕了。我只想在程序發送消息時用戶可以看到的東西。有沒有辦法將進度條與try相關聯?我的意思是,加載到TRY中的所有過程完成? – Nath 2012-03-07 18:34:12

+0

當然。在嘗試之前顯示它,並將其隱藏在最後。 – 2012-03-07 18:35:22

回答

0

現在,當我點擊「發送」,我的計劃只是沉默。

SmtpClient.Send(MailMessage)不是異步調用,因此會阻止調用線程,直到操作完成。

或者,您可以發送帶有SmtpClient.SendAsync(MailMessage, Object)的消息,這些消息將異步發起呼叫,從而允許您顯示所需的任何類型的等待對話框,直到發送完成。

然後,您可以設置回調函數,將操作報告給用戶。在上面鏈接的MSDN文章中有一個很好的例子。

0

你可以在UI線程上啓動這一進程,並通過更新你以上(或在幾個點)方法的進度條的一半,但這不是這樣的理想方式。理想情況下,您需要(取決於每條消息需要多長時間,或者確實需要發送多少條消息)在單獨的線程上啓動您的工作流程。

備註:如果這不是一個足夠長的運行過程這可能是矯枉過正。

一個簡單的方法爲使用線程是使用BackgroundWorker。因此,假設這是一個足夠長的運行過程或東西,你可能會在未來擴展到一批發送多封郵件可以按如下方式在後臺線程啓動此:

using System.Threading; 

    // Threading. 
    private BackgroundWorker bgWorker; 
    AutoResetEvent areProgressChanged = new AutoResetEvent(false); 

    private void SendYourMessage() 
    { 
     Stopwatch stopwatch = new Stopwatch(); 
     stopwatch.Start(); 
     try 
     { 
      MySqlDataAdapter adapter = new MySqlDataAdapter(); 
      MySqlCommand cmd = new MySqlCommand(getEmail, connect.connection); 
      cmd.Parameters.AddWithValue("@section", sectionSelect.SelectedValue); 
      adapter.SelectCommand = cmd; 

      // Show your progress. 
      (bgWorker as BackgroundWorker).ReportProgress(progressBarValue, "Half Way through..."); 

      DataTable mailingList = new DataTable(); 
      adapter.Fill(mailingList); 

      foreach (DataRow row in mailingList.Rows) 
      { 
       string rows = string.Format("{0}", row.ItemArray[0]); 
       message.To.Add(rows); 
      } 

      SmtpClient client = new SmtpClient(); 
      client.Credentials = new NetworkCredential(email, password.Password); 
      client.Host = "smtp.gmail.com"; 
      client.Port = 587; 
      client.EnableSsl = true; 
      client.Send(message); 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(ex.Message); 
     } 
     finally 
     { 
      stopwatch.Stop(); 
      TimeSpan timeTaken = stopwatch.Elapsed; 
      MessageBox.Show(String.Format("Your message has been sent. That took {0}s", timeTaken.Seconds)); 
     } 
    } 

    private void SendMyMessage_Click(object sender, EventArgs e) 
    { 
     // Start job on new thread. 
     bgWorker = new BackgroundWorker { WorkerReportsProgress = true, WorkerSupportsCancellation = true }; 
     bgWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork); 
     bgWorker.ProgressChanged += new ProgressChangedEventHandler(bgWorker_ProgressChanged); 
     bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorker_RunWorkerCompleted); 
     bgWorker.RunWorkerAsync(); 
    } 

    void bgWorker_DoWork(object sender, DoWorkEventArgs e) 
    { 
     BackgroundWorker thisWorker = sender as BackgroundWorker; 
     SendYourMessage(); 
    } 

    void bgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) 
    { 
     // Change progress bar (and form label). 
     this.progressBar.Value = e.ProgressPercentage; 
     this.label.Text = e.UserState; 

     // Tell the worker that the UIThread has been updated. 
     this.areProgressChanged.Set(); 
     return; 
    } 

    // Once the work is complete do something. 
    void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     // Handle. 
     if (e.Cancelled || bgWorker.CancellationPending) 
      MessageBox.Show("Message cancelled at users request!"); 
     else if (e.Error != null) 
      MessageBox.Show(String.Format("Error: {0}.", e.Error.ToString())); 
     return; 
    } 

    // To cancel the job. 
    private void cancelAsyncButton_Click(System.Object sender, System.EventArgs e) 
    { 
     if (bgWorker.WorkerSupportsCancellation) 
      bgWorker.CancelAsync(); 
    } 

此代碼可能需要調整。本質上,你設置了一些事件來啓動你的過程(這裏是SomeEvent_Click事件),這是BackgroundgroundWorker的入口點,我在這裏使用的其他事件可以在MSDN上閱讀。

祝你好運。