@Title
如何确定发送邮件所需的时间?
现在,当我点击“发送”时,我的程序只是沉默。我希望程序显示类似于程序发送消息时将加载的进度条。
这可能吗?
截至目前,这就是我所拥有的:
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 :(得分:0)
现在,当我点击“发送”时,我的程序只是沉默。
SmtpClient.Send(MailMessage)
不是异步调用,因此会阻止调用线程直到操作完成。
或者,您可以发送带有SmtpClient.SendAsync(MailMessage, Object)的消息,该消息将异步调用,允许您在发送完成之前显示任何类型的等待对话框。
然后,您可以设置一个回调函数,将该操作报告给用户完成。在我上面链接的MSDN文章中有一个很好的例子。
答案 1 :(得分: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
的入口点,我在这里使用的其他事件你可以在{{3 }}