2

我做了一个小程序,基本上可以通过 yahoo 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("myid@yahoo.com");
                    message.To.Add("anotherid@yahoo.com");
                    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 Niedermair 现在我刚刚尝试了该程序并将其放置了一分钟,然后显示错误:检测到 ContextSwitchDeadlock 消息:CLR 无法从 COM 上下文 0x21eb78 转换到 COM 上下文 0x21ece8 60 秒。拥有目标上下文/单元的线程很可能要么进行非泵送等待,要么处理非常长时间运行的操作而不泵送 Windows 消息。这种情况通常会对性能产生负面影响,甚至可能导致应用程序变得无响应或内存使用量随着时间的推移不断累积。为避免此问题,所有单线程单元 (STA) 线程都应使用泵送等待原语(例如 CoWaitForMultipleHandles)并在长时间运行的操作期间定期泵送消息。

谢谢你的帮助!

4

2 回答 2

1

catch有得到吗?

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

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

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

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

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

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

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

编辑:

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

于 2010-11-24T17:37:49.497 回答
0

根据 Andreas Niedermair 的编辑,问题是您阻塞主线程超过 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("myid@yahoo.com");
                message.To.Add("anotherid@yahoo.com");
                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 Niedermair 的建议,这是一个使用异步方法的版本。

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("myid@yahoo.com");
            message.To.Add("anotherid@yahoo.com");
            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");
    }
}
于 2010-11-24T18:56:36.823 回答