2012-03-07 2 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' не сообщает о промежуточном статусе. –

+0

Жаль. Я просто хотел что-то, что пользователь может видеть, пока программа отправляет сообщения. Есть ли способ связать индикатор выполнения с попыткой? Я имею в виду, нагрузка до тех пор, пока все процедуры в TRY не будут выполнены? – Nath

+0

Конечно. Покажите его перед попыткой и спрячьте его в конце. –

ответ

0

Прямо сейчас, когда я нажимаю «отправить», моя программа просто молчит.

SmtpClient.Send(MailMessage) не является асинхронным вызовом и, следовательно, блокирует вызывающий поток до завершения операции.

В качестве альтернативы вы можете отправить сообщение с SmtpClient.SendAsync(MailMessage, Object), которое сделает асинхронный вызов, позволяя вам отображать любое диалоговое окно ожидания, которое вы хотите, до тех пор, пока отправка не завершится.

Затем вы можете настроить функцию обратного вызова, которая сообщает о завершении операции пользователю. Это хороший пример этого в статье I MSDN, приведенной выше.

0

Вы можете запустить этот процесс в потоке пользовательского интерфейса и обновить индикатор выполнения на полпути через ваш метод выше (или в нескольких точках), но это не идеальный способ сделать это. В идеале вы бы хотели (в зависимости от того, сколько времени занимает каждое сообщение или сколько сообщений, которые вы отправляете), запустите свой рабочий процесс в отдельном потоке.

Примечание: это может быть излишним, если это недостаточно длительный процесс.

Простым способом использования резьбы является использование 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.

Удачи.

Смежные вопросы