1

所以我试图延迟从我的程序发送电子邮件。为了保持 UI 的交互性,我启动了一个新线程并在线程中调用 email 方法。有用。它发送电子邮件。但是我不知道如何让线程休眠。我尝试在实际的电子邮件方法中使用 Thread.sleep(),但它似乎不起作用。

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
    }
4

2 回答 2

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来解释为什么这不是一个好主意)。

于 2012-10-02T00:51:14.827 回答
0

由于您对编程有点陌生,因此我不会尝试解释所有相关细节,但我认为您向我展示了您的示例的新技巧很酷,所以如果可以的话,我想帮助您。

这不是编写此代码的唯一方法,但我可以告诉您这是一种合理的方法。它使用后台工作组件在发送电子邮件时保持 UI 响应。注意后台工作人员提供的事件 DoWork 和 RunWorkerCompleted 的使用。这些事件的设置发生在设计器中,这就是为什么我为您压缩解决方案以便您可以查看整个事情(我使用 google Drive 这样做,这是我第一次尝试公开共享 - 如果链接会像我一样为您打开,您将获得一个文件菜单,您可以从中选择下载)。

我创建了一个内部私有类并将其传递给后台工作人员。我这样做是因为我不想通过在不同线程中运行的代码访问我的 UI 组件中的数据。这并不总是会导致问题,但我发现它通常是一个很好的做法。此外,如果我想稍后重构代码,它会更容易从 DoWork 中获取这些行并将它们放在其他地方而不会大惊小怪。

在多线程编程的更一般领域 - 它是一个多方面的主题,您不需要立即了解它。 是我最喜欢的教程(这本书也很棒)。

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);
        }
    }
}
于 2012-10-02T01:57:45.803 回答