Почему программа Send-Email зависает? - PullRequest
2 голосов
/ 24 ноября 2010

Я создал небольшую программу, в которой я могу отправлять электронные письма через SMTP-сервер Yahoo.Мой код:

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 до контекста 0x21ece8 в течение 60 секунд.Поток, которому принадлежит целевой контекст / квартира, скорее всего, либо делает ожидание без перекачки, либо обрабатывает очень длительную операцию без перекачки сообщений Windows.Эта ситуация, как правило, оказывает негативное влияние на производительность и может даже привести к тому, что приложение перестает отвечать на запросы или использование памяти постоянно увеличивается с течением времени.Чтобы избежать этой проблемы, все потоки однопоточных квартир (STA) должны использовать примитивы перекачки (такие как CoWaitForMultipleHandles) и регулярно перекачивать сообщения во время длительных операций.

Спасибо за вашу помощь!

Ответы [ 2 ]

1 голос
/ 24 ноября 2010

достигает ли catch когда-либо?

Я предполагаю, что вы недостаточно терпеливы, чтобы достичь значения по умолчанию свойства Timeout (100 секунд) ... Вы можете уменьшить значение, чтобы получить более раннее завершение.

Пока вы не работаете с асинхронным шаблоном, ваш поток пользовательского интерфейса все равно блокируется. альтернативой может быть использование метода SendAsync (в записях msdn есть примеры реализаций для конкретных методов).

Изменить:
как автор упомянул возможный порт **, да, это может быть. но вам придется прочитать документ с описанием , в котором говорится:

  • SMTP-сервер: plus.smtp.mail.yahoo.com
  • Использовать SSL
  • Порт: 465
  • Использовать аутентификацию
  • Имя учетной записи / Имя для входа: Ваш Yahoo! Идентификатор почты (ваш адрес электронной почты без «@ yahoo.com», например, «testing80»)
  • Адрес электронной почты: Ваш Yahoo! Почтовый адрес (например, testing80@yahoo.com)
  • Пароль: Ваш Yahoo! Почтовый пароль
  • [...] попробуйте установить номер порта SMTP на 587 при отправке электронной почты через SMTP-сервер Yahoo !.

но даже если вы соответствуете спецификациям: вы действительно должны использовать асинхронный шаблон:)

Edit: упомянутое исключение связано с COM ... немного гуглинг, и я нашел this :

Что, вероятно, происходит, что вы иметь COM-объект в форме, и вы делаете работу в потоке пользовательского интерфейса. Если ваш пользовательский интерфейс блокируется обработкой в течение> 60 секунд компонент COM может жалуются.

Edit:

в противном случае: вы что-нибудь изменили в диалоге исключений Visual Studio? тогда это может быть ваше решение или это (с некоторыми базовыми объяснениями) ...

0 голосов
/ 24 ноября 2010

Согласно Андреасу Нидермайру, проблема заключается в том, что вы блокируете основной поток более чем на 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();
        }
    }

}

РЕДАКТИРОВАТЬ:

согласно совету Андреаса Нидермейра, здесь есть версия, в которой вместо этого используется асинхронный метод.

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");
    }
}
...