所以我试图延迟从我的程序发送电子邮件。 为了保持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
}
答案 0 :(得分: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以获取解释为什么这不是一个好主意)。
答案 1 :(得分:0)
由于你对编程有点新意,我不会尝试解释所有相关的细节,但我认为你向我展示了一个新的技巧很酷,所以我想帮助你,如果可以的话。< / p>
这不是唯一的编码方式,但我可以告诉你这是一个合理的方法。它使用后台工作程序组件在发送电子邮件时保持UI响应。请注意后台工作者提供的事件DoWork和RunWorkerCompleted的使用。这些事件的设置发生在设计师中,这就是为什么我zipped the solution up for you所以你可以看一下整个事情(我用谷歌驱动器这样做,这是我第一次尝试公开分享 - 如果链接打开就像它对我一样,你会得到一个文件菜单,你可以从中选择下载。
我创建了一个内部私有类并将其传递给后台worker。我这样做是因为我不想从在不同线程中运行的代码访问我的UI组件中的数据。这并不总是会引起问题,但我发现这是一个很好的做法。此外,如果我想稍后重构代码,那么就更容易从DoWork获取行并将它们放在其他地方而不用大惊小怪。
在多线程编程的更一般领域 - 它是一个多方面的主题,你不需要立即得到它。 This是我最喜欢的教程(这本书也很棒)。
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);
}
}
}