C# 发送邮件时显示闪烁的消息
目标:我需要在单击发送按钮后,在发送电子邮件时显示一个闪烁的按钮文本,即“发送” 问题:发送电子邮件需要一些时间。同时,表单被冻结。发送消息后,将显示闪烁的消息 尝试的方法: 1) 使用两个计时器,一个用于显示闪烁的标签消息,另一个用于发送。 2) 已使用的Application.DoEvents() 代码:C# 发送邮件时显示闪烁的消息,c#,winforms,.net-3.5,C#,Winforms,.net 3.5,目标:我需要在单击发送按钮后,在发送电子邮件时显示一个闪烁的按钮文本,即“发送” 问题:发送电子邮件需要一些时间。同时,表单被冻结。发送消息后,将显示闪烁的消息 尝试的方法: 1) 使用两个计时器,一个用于显示闪烁的标签消息,另一个用于发送。 2) 已使用的Application.DoEvents() 代码: private void BtnSend_Click(object sender, EventArgs e) { try
private void BtnSend_Click(object sender, EventArgs e)
{
try
{
TimrSending.Start();
OleDbDataReader hold = cdbc.connectDB("SELECT UserID, PassWord, EmailID from Tbl_RegisteredUser where UserID='" + TxtUserID.Text + "' and AF=true");
hold.Read();
SendMailNew(hold[0].ToString(), hold[1].ToString(), hold[2].ToString());
cdbc.disconectDB();
MessageBox.Show("Message sent successfully! \n Please check your registered Email address for the password");
cdbc.disconectDB();
this.Close();
//Application.DoEvents();
this.TimrSending.Stop();
}
catch (Exception)
{
cdbc.disconectDB();
this.TimrSent.Stop();
BtnSend.Text = "Send";
MessageBox.Show("Message sending failed! \n Exeption" + e.ToString(), "Email Failure", MessageBoxButtons.OK);
}
}
private void TimrSending_Tick(object sender, EventArgs e)
{
if (flag == true)
{
BtnSend.Text = "Sending";
flag = false;
//Application.DoEvents();
}
else
{
BtnSend.Text = "..Sending..";
flag = true;
//Application.DoEvents();
}
//System.Threading.Thread.Sleep(2000);
}
如前所述,
SendMailNew()
函数可能会阻塞UI线程,因此您看不到“计时器”的预期结果
有几种方法可以剥这只猫的皮。在我看来,一种简单、直接且经过测试的代码修补方法是实现BackgroundWorker
。通过这样做,您可以在线程上抛出SendMailNew()
函数,并切换UI控件而不会出现问题。一些代码:
private void BtnSend_Click(object sender, EventArgs e)
{
try
{
BackgroundWorker SendMail = new BackgroundWorker()
{
WorkerSupportsCancellation = true
};
SendMail.DoWork += SendMail_DoWork;
SendMail.RunWorkerCompleted += SendMail_RunWorkerCompleted;
TimrSending.Start();
OleDbDataReader hold = cdbc.connectDB("SELECT UserID, PassWord, EmailID from Tbl_RegisteredUser where UserID='" + TxtUserID.Text + "' and AF=true");
hold.Read();
List<string> parameters = new List<string>() {hold[0].ToString(), hold[1].ToString(), hold[2].ToString()};
SendMail.RunWorkerAsync(parameters);
}
catch (Exception)
{
cdbc.disconectDB();
this.TimrSent.Stop();
BtnSend.Text = "Send";
MessageBox.Show("Message sending failed! \n Exeption" + e.ToString(), "Email Failure", MessageBoxButtons.OK);
}
}
private void SendMail_DoWork(object sender, DoWorkEventArgs e)
{
List<string> args = (List<string>) e.Argument;
try
{
SendMailNew(args[0], args[1], args[2]);
e.Result = true;
}
catch(Exception ex)
{
e.Result = false;
}
}
void SendMail_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if(e.Result)
{
cdbc.disconectDB();
MessageBox.Show("Message sent successfully! \n Please check your registered Email address for the password");
cdbc.disconectDB();
this.Close();
//Application.DoEvents();
this.TimrSending.Stop();
}
else
{
// Fail
}
}
private void TimrSending_Tick(object sender, EventArgs e)
{
BtnSend.Text = flag ? "Sending" : "..Sending..";
flag = !flag;
}
private void btn发送\u单击(对象发送者,事件参数e)
{
尝试
{
BackgroundWorker SendMail=新的BackgroundWorker()
{
WorkerSupportsScanCellation=真
};
SendMail.DoWork+=SendMail\u DoWork;
SendMail.RunWorkerCompleted+=SendMail\u RunWorkerCompleted;
TimrSending.Start();
OleDbDataReader hold=cdbc.connectDB(“从Tbl_RegisteredUser中选择UserID、密码、EmailID,其中UserID=”“+TxtUserID.Text+”,AF=true”);
hold.Read();
列表参数=新列表(){hold[0]。ToString(),hold[1]。ToString(),hold[2]。ToString()};
RunWorkerAsync(参数);
}
捕获(例外)
{
cdbc.disconnectdb();
this.TimrSent.Stop();
BtnSend.Text=“发送”;
MessageBox.Show(“消息发送失败!\n Exeption”+e.ToString(),“电子邮件失败”,MessageBox按钮。确定);
}
}
私有void SendMail_DoWork(对象发送者,DoWorkEventArgs e)
{
List args=(List)e.参数;
尝试
{
SendMailNew(参数[0],参数[1],参数[2]);
e、 结果=真;
}
捕获(例外情况除外)
{
e、 结果=假;
}
}
void SendMail\u RunWorkerCompleted(对象发送方,RunWorkerCompletedEventArgs e)
{
如果(如结果)
{
cdbc.disconnectdb();
MessageBox.Show(“消息已成功发送!\n请检查您注册的电子邮件地址以获取密码”);
cdbc.disconnectdb();
这个。关闭();
//Application.DoEvents();
this.TimrSending.Stop();
}
其他的
{
//失败
}
}
私有void TimrSending_Tick(对象发送方,事件参数e)
{
BtnSend.Text=标志“发送”:“.Sending..”;
flag=!flag;
}
所有完成代码现在都在RunWorkerCompleted()
中,它在SendMailNew()
函数从DoWork()
启动的单独线程返回后运行。我还略微优化了TimerSending_Tick()
方法,但在功能上做了相同的事情
编辑:在良好的实践中,您可能需要检查以使
SendMailNew()
成功执行。最好的方法是利用DowWorkEventArgs
和RunWorkerCompletedEventArgs
中提供给您的Result
参数,因为您的主线程将无法捕获来自SendMailNew的错误。相应地更新了代码。如果需要检查错误,请在e.Result中返回消息。为了不阻塞UI线程,请在单独的线程上运行“闪烁消息”任务BackgroundWorker
对于您的案例非常有用(您还可以利用它的ReportProgress
事件)。阅读更多关于定时器的问题是什么?谢谢Glace,我花了一段时间才理解这些函数的含义。但现在多亏了你,我学到了一些关于线程的知识。最后但并非最不重要的一点,你的答案正是我所需要的:)@VAR不是问题。线程不是一个容易的话题;Backgroundworker为您提供了一种很好的、结构化的方法来利用线程的优势,而无需为管理线程而头疼。祝你好运,如果你需要关于上述解决方案的任何进一步解释,我很乐意提供帮助。嗯,我确实对“列表”这件事有疑问。我确实尝试过通过在SendMail工作中插入“Select&hold”部分来消除整个列表,但效果不是很好。不知道为什么。无论如何,谢谢你&很抱歉给你添麻烦:)