为什么发送电子邮件程序冻结?

发布于 2024-10-04 09:54:13 字数 2159 浏览 1 评论 0原文

我制作了一个小程序,在其中我基本上可以通过雅虎 smtp 服务器发送电子邮件。我的代码:

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Net;
using System.Net.Mail;
using System.Drawing;
using System.IO;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {

                try
                {

                    MailMessage message = new MailMessage();
                    message.From = new MailAddress("[email protected]");
                    message.To.Add("[email protected]");
                    message.Subject = "afdasdfasfg";
                    message.Body = "Hgfk4564267862738I";
                    message.IsBodyHtml = true;
                    message.Priority = MailPriority.High;
                    SmtpClient sC = new SmtpClient("smtp.mail.yahoo.com");
                    sC.Port = 587;
                    sC.Credentials = new NetworkCredential("myid", "mypassword");
                    //sC.EnableSsl = true;
                    sC.Send(message);
                    MessageBox .Show ("Mail Send Successfully");

                }
                catch (Exception ex)
                {
                    MessageBox .Show (ex + "Mail Sending Fail's") ;

                }
            }

        }
    }

奇怪的是它在第一周就起作用了。我可以毫无问题地发送消息。然后就在昨天,程序开始冻结并且没有响应(我没有更改代码)。为什么会发生这种情况?我该如何修改我的程序?

编辑:@Andreas Niederair 现在我刚刚尝试了该程序并保留了整整一分钟,然后显示错误:检测到 ContextSwitchDeadlock 消息:CLR 60 秒内无法从 COM 上下文 0x21eb78 转换到 COM 上下文 0x21ece8。拥有目标上下文/单元的线程很可能执行非泵送等待或处理非常长时间运行的操作而不泵送 Windows 消息。这种情况通常会对性能产生负面影响,甚至可能导致应用程序变得无响应或内存使用量随着时间的推移不断累积。为了避免此问题,所有单线程单元 (STA) 线程都应使用泵送等待原语(例如 CoWaitForMultipleHandles),并在长时间运行的操作期间定期泵送消息。

感谢您的帮助!

I made a small program in which I can basically send an email through the yahoo smtp server. My Code:

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Net;
using System.Net.Mail;
using System.Drawing;
using System.IO;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {

                try
                {

                    MailMessage message = new MailMessage();
                    message.From = new MailAddress("[email protected]");
                    message.To.Add("[email protected]");
                    message.Subject = "afdasdfasfg";
                    message.Body = "Hgfk4564267862738I";
                    message.IsBodyHtml = true;
                    message.Priority = MailPriority.High;
                    SmtpClient sC = new SmtpClient("smtp.mail.yahoo.com");
                    sC.Port = 587;
                    sC.Credentials = new NetworkCredential("myid", "mypassword");
                    //sC.EnableSsl = true;
                    sC.Send(message);
                    MessageBox .Show ("Mail Send Successfully");

                }
                catch (Exception ex)
                {
                    MessageBox .Show (ex + "Mail Sending Fail's") ;

                }
            }

        }
    }

The bizarre thing is that it worked for the first week. I could send messages with no problem. Then just yesterday, the program just starts freezing and doesn't respond( I didn't change the code). Why did this happen? How can I mend my program?

Edit: @Andreas Niedermair Right now I just tried the program and left it for a whole minute then an error showed:ContextSwitchDeadlock was detected
Message: The CLR has been unable to transition from COM context 0x21eb78 to COM context 0x21ece8 for 60 seconds. The thread that owns the destination context/apartment is most likely either doing a non pumping wait or processing a very long running operation without pumping Windows messages. This situation generally has a negative performance impact and may even lead to the application becoming non responsive or memory usage accumulating continually over time. To avoid this problem, all single threaded apartment (STA) threads should use pumping wait primitives (such as CoWaitForMultipleHandles) and routinely pump messages during long running operations.

Thanks for your help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

·深蓝 2024-10-11 09:54:13

你的catch能到达吗?

我假设您没有足够的耐心达到 Timeout 属性的默认值(100 秒)...
您可以减少该值以获得更早的完成。

只要您不使用异步模式,您的 UI 线程就会被阻塞。另一种方法是使用 SendAsync 方法(具体方法的 msdn-entries 中有示例实现)。

编辑:
正如作者提到的一个可能的端口:是的,有可能。但您必须阅读规范文件,它告诉我们:

  • SMTP 服务器:plus.smtp.mail.yahoo.com
  • 使用 SSL
  • 端口:465
  • 使用身份验证
  • 帐户名/登录名:您的 Yahoo!邮件 ID(您的电子邮件地址,不带“@yahoo.com”,例如“testing80”)
  • 电子邮件地址:您的 Yahoo!邮件地址(例如,[电子邮件受保护]
  • 密码:您的 Yahoo!邮件密码
  • [...] 通过 Yahoo! 的 SMTP 服务器发送电子邮件时,尝试将 SMTP 端口号设置为 587。

但即使你满足规范:你真的应该选择异步模式:)

编辑:
提到的异常与 COM 有关...有点谷歌搜索,我发现 这个

可能发生的情况是,您
在表单中有一个 COM 对象,并且
你正在 UI 线程上工作。如果
你的 UI 被处理阻塞
超过 60 秒,COM 组件可以
抱怨。

编辑:

否则:您是否在 Visual Studio 的异常对话框中更改了任何内容?那么这可能是您的解决方案,或这个(有一些基本解释)...

does your catch ever get reached?

i assume, that you are not patient enough to reach the default value of the Timeout property (100seconds)...
you could decrease the value to get an earlier completion.

as long as you are not working with an async-pattern, your UI-thread gets blocked anyway. an alternative would be to use the SendAsync method (there are sample implementations in the msdn-entries for the specific methods).

Edit:
as the author mentioned a possible fu**ed port: yes, it could be. but you would have to read the specification paper, which tells us:

  • SMTP server: plus.smtp.mail.yahoo.com
  • Use SSL
  • Port: 465
  • Use authentication
  • Account Name/Login Name: Your Yahoo! Mail ID (your email address without the "@yahoo.com", for example, “testing80”)
  • Email Address: Your Yahoo! Mail address (for example, [email protected])
  • Password: Your Yahoo! Mail password
  • [...] try setting the SMTP port number to 587 when sending email via Yahoo!'s SMTP server.

but even if you meet the specifications: you should really go for the async-pattern :)

Edit:
the mentioned exception is related to COM ... a bit googeling, and i've found this:

What's probably happening is that you
have a COM object in a form, and
you're doing work on the UI thread. If
your UI gets blocked by the processing
for >60 seconds, the COM component can
complain.

Edit:

otherwise: did you change anything within the exceptions-dialog of visual studio? then this could be your solution, or this one (with some basic explanation)...

一片旧的回忆 2024-10-11 09:54:13

根据 Andreas Niederair 的编辑,问题是您阻塞主线程超过 60 秒。最好的办法是将此操作放在后台线程上。

using System;
using System.ComponentModel;
using System.Net;
using System.Net.Mail;
using System.Windows.Forms;

namespace Sandbox_Form
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            bw = new BackgroundWorker();
            bw.DoWork +=new DoWorkEventHandler(bw_DoWork);
            bw.RunWorkerCompleted +=new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
        }

        void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if(e.Error != null)
                MessageBox.Show(e.Error.ToString() + "Mail Sending Fail's") ;
            else
                MessageBox.Show("Mail Send Successfully");
        }

        BackgroundWorker bw;

        void bw_DoWork(object sender, DoWorkEventArgs e)
        {
            using(MailMessage message = new MailMessage())
            {
                message.From = new MailAddress("[email protected]");
                message.To.Add("[email protected]");
                message.Subject = "afdasdfasfg";
                message.Body = "Hgfk4564267862738I";
                message.IsBodyHtml = true;
                message.Priority = MailPriority.High;
                using(SmtpClient sC = new SmtpClient("smtp.mail.yahoo.com"))
                {
                    sC.Port = 587;
                    sC.Credentials = new NetworkCredential("myid", "mypassword");
                    //sC.EnableSsl = true;
                    sC.Send(message);
                }
            }
        }
        private void button1_Click(object sender, EventArgs e)
        {
            bw.RunWorkerAsync();
        }
    }

}

编辑:

根据 Andreas Niederair 的建议,这里是一个使用异步方法的版本。

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
    private void button1_Click(object sender, EventArgs e)
    {
        try
        {

            MailMessage message = new MailMessage();
            message.From = new MailAddress("[email protected]");
            message.To.Add("[email protected]");
            message.Subject = "afdasdfasfg";
            message.Body = "Hgfk4564267862738I";
            message.IsBodyHtml = true;
            message.Priority = MailPriority.High;
            SmtpClient sC = new SmtpClient("smtp.mail.yahoo.com");
            sC.Port = 587;
            sC.Credentials = new NetworkCredential("myid", "mypassword");
            //sC.EnableSsl = true;
            //sC.Send(message);
            sC.SendCompleted += new SendCompletedEventHandler(sC_SendCompleted);
            sC.SendAsync(message, null);

        }
        catch (Exception ex)
        {
            MessageBox.Show(ex + "Mail Sending Fail's");
        }

    }

    void sC_SendCompleted(object sender, AsyncCompletedEventArgs e)
    {
        if(e.Error != null)
            MessageBox.Show(ex + "Mail Sending Fail's");
        else
            MessageBox.Show("Mail Send Successfully");
    }
}

As per Andreas Niedermair edit the issue is you are blocking the main thread for more than 60 secconds. The best thing to do is put this operation on a background thread.

using System;
using System.ComponentModel;
using System.Net;
using System.Net.Mail;
using System.Windows.Forms;

namespace Sandbox_Form
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            bw = new BackgroundWorker();
            bw.DoWork +=new DoWorkEventHandler(bw_DoWork);
            bw.RunWorkerCompleted +=new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
        }

        void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if(e.Error != null)
                MessageBox.Show(e.Error.ToString() + "Mail Sending Fail's") ;
            else
                MessageBox.Show("Mail Send Successfully");
        }

        BackgroundWorker bw;

        void bw_DoWork(object sender, DoWorkEventArgs e)
        {
            using(MailMessage message = new MailMessage())
            {
                message.From = new MailAddress("[email protected]");
                message.To.Add("[email protected]");
                message.Subject = "afdasdfasfg";
                message.Body = "Hgfk4564267862738I";
                message.IsBodyHtml = true;
                message.Priority = MailPriority.High;
                using(SmtpClient sC = new SmtpClient("smtp.mail.yahoo.com"))
                {
                    sC.Port = 587;
                    sC.Credentials = new NetworkCredential("myid", "mypassword");
                    //sC.EnableSsl = true;
                    sC.Send(message);
                }
            }
        }
        private void button1_Click(object sender, EventArgs e)
        {
            bw.RunWorkerAsync();
        }
    }

}

EDIT:

per Andreas Niedermair suggestion, here is a version using the async method instead.

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
    private void button1_Click(object sender, EventArgs e)
    {
        try
        {

            MailMessage message = new MailMessage();
            message.From = new MailAddress("[email protected]");
            message.To.Add("[email protected]");
            message.Subject = "afdasdfasfg";
            message.Body = "Hgfk4564267862738I";
            message.IsBodyHtml = true;
            message.Priority = MailPriority.High;
            SmtpClient sC = new SmtpClient("smtp.mail.yahoo.com");
            sC.Port = 587;
            sC.Credentials = new NetworkCredential("myid", "mypassword");
            //sC.EnableSsl = true;
            //sC.Send(message);
            sC.SendCompleted += new SendCompletedEventHandler(sC_SendCompleted);
            sC.SendAsync(message, null);

        }
        catch (Exception ex)
        {
            MessageBox.Show(ex + "Mail Sending Fail's");
        }

    }

    void sC_SendCompleted(object sender, AsyncCompletedEventArgs e)
    {
        if(e.Error != null)
            MessageBox.Show(ex + "Mail Sending Fail's");
        else
            MessageBox.Show("Mail Send Successfully");
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文