Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/268.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 发送邮件时显示闪烁的消息_C#_Winforms_.net 3.5 - Fatal编程技术网

C# 发送邮件时显示闪烁的消息

C# 发送邮件时显示闪烁的消息,c#,winforms,.net-3.5,C#,Winforms,.net 3.5,目标:我需要在单击发送按钮后,在发送电子邮件时显示一个闪烁的按钮文本,即“发送” 问题:发送电子邮件需要一些时间。同时,表单被冻结。发送消息后,将显示闪烁的消息 尝试的方法: 1) 使用两个计时器,一个用于显示闪烁的标签消息,另一个用于发送。 2) 已使用的Application.DoEvents() 代码: private void BtnSend_Click(object sender, EventArgs e) { try

目标:我需要在单击发送按钮后,在发送电子邮件时显示一个闪烁的按钮文本,即“发送”

问题:发送电子邮件需要一些时间。同时,表单被冻结。发送消息后,将显示闪烁的消息

尝试的方法: 1) 使用两个计时器,一个用于显示闪烁的标签消息,另一个用于发送。 2) 已使用的Application.DoEvents()

代码:

 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”部分来消除整个列表,但效果不是很好。不知道为什么。无论如何,谢谢你&很抱歉给你添麻烦:)