2010-11-24 7 views
1

J'ai fait un petit programme dans lequel je peux essentiellement envoyer un email via le serveur yahoo smtp. Mon code:Pourquoi le programme Send-Email Freeze?

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

       } 
      } 

     } 
    } 

La chose bizarre est que cela a fonctionné pour la première semaine. Je pourrais envoyer des messages sans problème. Hier encore, le programme commence à geler et ne répond pas (je n'ai pas changé le code). Pourquoi est-ce arrivé? Comment puis-je réparer mon programme?

Edit: @Andreas Niedermair En ce moment, je viens d'essayer le programme et l'a laissé pendant une minute, une erreur a montré: ContextSwitchDeadlock a été détectée Message: Le CLR a été incapable de faire la transition à partir du contexte COM 0x21eb78 au contexte COM 0x21ece8 pour 60 secondes. Le thread qui possède le contexte/appartement de destination est probablement en train de faire une attente sans pompage ou de traiter une opération très longue sans pomper les messages Windows. Cette situation a généralement un impact négatif sur les performances et peut même conduire à une non-réactivité de l'application ou à une accumulation continue de l'utilisation de la mémoire au fil du temps. Pour éviter ce problème, tous les threads STA (single threaded apartment) doivent utiliser des primitives d'attente de pompage (telles que CoWaitForMultipleHandles) et pomper régulièrement des messages lors d'opérations longues.

Merci pour votre aide!

+1

Avez-vous essayé de le déboguer pour voir où il est suspendu? – Bernard

+0

avec quel framework .net travaillez-vous? –

Répondre

1

Votre catch jamais obtenir atteint?

je suppose, que vous n'êtes pas assez patient pour atteindre la valeur par défaut des Timeout propriété (100 secondes) ... vous pouvez diminuer la valeur pour obtenir une version antérieure d'achèvement.

aussi longtemps que vous ne travaillez pas avec un async-modèle, votre interface utilisateur-fil est bloqué de toute façon. une alternative consisterait à utiliser la méthode SendAsync (il existe des exemples d'implémentations dans les entrées msdn pour les méthodes spécifiques).

Edit:
que l'auteur a mentionné un possible fu ** port ed: oui, il pourrait être. mais vous devez lire le specification paper, qui nous dit:

  • serveur SMTP: plus.smtp.mail.yahoo.com
  • SSL
  • Port: 465
  • Utiliser l'authentification
  • Nom du compte/Nom de connexion: Votre compte Yahoo! Mail ID (votre adresse e-mail sans le "@ yahoo.com", par exemple, "testing80")
  • Adresse e-mail: Votre Yahoo! Adresse e-mail (par exemple, [email protected])
  • Mot de passe: votre compte Yahoo! Mot de passe Mail
  • [...] essayez de définir le numéro de port SMTP sur 587 lors de l'envoi d'e-mails via le serveur SMTP de Yahoo !.

mais même si vous répondez aux spécifications: vous devriez vraiment aller pour le async motif :)

Edit: l'exception mentionnée est liée à COM ...un peu googeling, et je l'ai trouvé this:

Ce qui se passe probablement est que vous avez un objet COM sous une forme et que vous faites le travail sur le thread d'interface utilisateur. Si votre interface utilisateur est bloquée par le traitement pendant> 60 secondes, le composant COM peut se plaindre.

Edit:

autrement: avez-vous changé quelque chose dans les exceptions-dialogue de Visual Studio? alors cela pourrait être votre solution, ou this one (avec quelques explications basiques) ...

+0

Pourriez-vous m'expliquer cela dans le code s'il vous plaît? –

+0

@Omar: réponse retravaillée –

+0

@Andreas Niedermair Pensez-vous qu'il pourrait y avoir un problème avec le port? –

0

Selon Andreas Niedermair, le problème est que vous bloquez le thread principal pendant plus de 60 secondes. La meilleure chose à faire est de mettre cette opération sur un fil de fond.

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:

par suggestion Andreas Niedermair, voici une version en utilisant la méthode async à la place.

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

avez-vous vraiment besoin de créer un nouveau backroundworker-thread? pourquoi ne pas utiliser la méthode 'SendAsync' avec un rappel? –

+0

Je ne connaissais pas la classe send, mais cela fonctionnerait aussi bien. Va ajouter un exemple. –

+2

@Andreas Niedermair, Un avantage à créer un thread de travail de fond séparé est que vous pouvez disposer des objets dès qu'ils sont faits au lieu d'attendre que le GC le fasse (à la fois 'MailMessage' et' StmpClient' implémentent 'IDisposeable') –

Questions connexes