如何确定SmtpClient.send发送消息所花费的时间?

时间:2012-03-07 18:25:54

标签: c#

@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.");
            }

2 个答案:

答案 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 }}

祝你好运。