Envoi d'un email, application se fige pendant quelques instants

Résolu
Karin.code Messages postés 183 Date d'inscription vendredi 2 septembre 2016 Statut Membre Dernière intervention 16 janvier 2018 - 30 déc. 2016 à 11:32
Karin.code Messages postés 183 Date d'inscription vendredi 2 septembre 2016 Statut Membre Dernière intervention 16 janvier 2018 - 3 janv. 2017 à 09:45
Bonjour,
dans mon application j'ai ajouté une partie qui me permet d'envoyer un message électronique avec une pièce jointe (taille maximale 15 Mo), dans cette partie il y a aucun problème tout fonction à la perfection, sauf qu'il y a une chose qui me dérange
quand j'envoi un message, l'application se fige pendant quelques instants (en fonction de la taille de la pièce jointe), voici le code que j'utilise :
Imports System.Net.Mail
Public Class Form1
Dim Compte As String
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
If ComboBox1.Text = "Gmail" Then 'le type de votre compte
Compte = "smtp.gmail.com"
End If
If ComboBox1.Text = "Hotmail" Then 'le type de votre compte
Compte = "smtp.live.com"
End If
If ComboBox1.Text = "Yahoo" Then 'le type de votre compte
Compte = "smtp.mail.yahoo.fr"
End If
Dim Mail As New MailMessage()
Dim Smtp As New SmtpClient(Compte)
If Not TextBoxFichier.Text = "" Then 'Chemin d'accès de la pièce jointe
Mail.Attachments.Add(New Attachment(TextBoxFichier.Text))
End If
Mail.From = New MailAddress(TextBoxEmail.Text) 'Votre email
Mail.To.Add(TextBoxEmailDestinateur.Text) 'email de celui a qui le message électronique sera envoyé
Mail.Subject = (TextBoxSujet.Text) 'Objet du message
Mail.Body = (TextBoxMessages.Text) 'Texte du message
Smtp.Port = ("587")
Smtp.Credentials = New System.Net.NetworkCredential(TextBoxEmail.Text, TextBoxMotdepasse.Text)
Smtp.EnableSsl = True
Try
Smtp.Send(Mail)
MessageBox.Show("Votre email a bien été envoyé", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information)
Catch ex As Exception
MessageBox.Show("le message n'a pas été envoyé veuillez réessayer plus tard", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information)
End Try
End Sub
End Class

j'ai essayé d'utiliser un
BackgroundWorker 
comme je l'ai utilisé dans un de mes anciens postes
http://codes-sources.commentcamarche.net/forum/affich-10070913-message-anime-pendant-qu-on-compte-le-nombre-de-fichier#23
Imports System.Net.Mail
Public Class Form1
Dim Compte As String
Dim Résultat As Boolean = False
Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
If ComboBox1.Text = "Gmail" Then 'le type de votre compte
Compte = "smtp.gmail.com"
End If
If ComboBox1.Text = "Hotmail" Then 'le type de votre compte
Compte = "smtp.live.com"
End If
If ComboBox1.Text = "Yahoo" Then 'le type de votre compte
Compte = "smtp.mail.yahoo.fr"
End If
Dim Mail As New MailMessage()
Dim Smtp As New SmtpClient(Compte)
If Not TextBoxFichier.Text = "" Then 'Chemin d'accès de la pièce jointe
Mail.Attachments.Add(New Attachment(TextBoxFichier.Text))
End If
Mail.From = New MailAddress(TextBoxEmail.Text) 'Votre email
Mail.To.Add(TextBoxEmailDestinateur.Text) 'email de celui a qui le message électronique sera envoyé
Mail.Subject = (TextBoxSujet.Text) 'Objet du message
Mail.Body = (TextBoxMessages.Text) 'Texte du message
Smtp.Port = ("587")
Smtp.Credentials = New System.Net.NetworkCredential(TextBoxEmail.Text, TextBoxMotdepasse.Text)
Smtp.EnableSsl = True
Try
Smtp.Send(Mail)
Résultat = True
Catch ex As Exception
Résultat = False
End Try
End Sub
End Class
Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
If Résultat = True Then
MessageBox.Show("Votre email a bien été envoyé", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information)
Else
MessageBox.Show("le message n'a pas été envoyé veuillez réessayer plus tard", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
End Sub

mais cela ne fonctionne pas (l'email n'est pas envoyer) et j'arrive pas à trouver dans quelle partie se situe le problème
je sollicite votre aide pour comprendre et régler ce problème
merci pour votre aide

3 réponses

Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 656
Modifié par Whismeril le 30/12/2016 à 21:35
Bonsoir

le mail n'est pas envoyé ou Resultat ne vaut pas True?

Parce que quoiqu'il advienne, ici
    Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
        If Résultat = True Then
            MessageBox.Show("Votre email a bien été envoyé", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information)
        Else
            MessageBox.Show("le message n'a pas été envoyé veuillez réessayer plus tard", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information)
        End If
    End Sub

il vaudra toujours False.

La portée d'une variable s'arrête "au premier End englobant".
Exemple
Class TrucMuche
    variable Machin

    Sub Toto
        Machin 'existe et est bien celui au dessus
   En Sub

   Sub Tata
      Machin 'est toujours le même
   End Sub

End Class

Machin 'n'existe pas

Class Bidouille
     variable Machin 'a le même nom mais ce n'est pas la même




Or dans ton code Resultat est déclaré dans la Sub abonnée à DoWork, donc c'est ce Resultat là qui est renseigné.

Quand tu arrives dans celle abonnée RunWorkCompleted,
  • soit tu n'as pas mis les options comme on te l'a déjà conseillé (Strict On, Explict, ect...) et VB se dit "tiens, une variable que je ne connais pas, alors j'en crée une avec sa valeur par défaut -> False.
  • soit tu as bien mis ces options, mais tu as déclaré un second Resultat, dont la portée englobe cette sub, mais c'est l'autre qui est renseigné.


Exemple
Class TrucMuche
    variable Machin

    Sub Toto
        Machin 'existe et est bien celui au dessus
   En Sub

   Sub Tata
      variable Machin', même nom donc bloque la portée de  l'autre
      'ce Machin n'aura aucune influence sur l'autre.
   End Sub

End Class


Donc selon le cas,
  • mettre les options strict et explicit à On
  • ne déclarer qu'une seule variable par nom dans une même classe, et lui donner la portée utile.Quand j'étais petit, la mer Morte n'était que malade.

George Burns
0
Karin.code Messages postés 183 Date d'inscription vendredi 2 septembre 2016 Statut Membre Dernière intervention 16 janvier 2018 2
31 déc. 2016 à 13:40
Bonjour Whismeril
Merci de m'avoir répondu
c'est vrai je n'ai pas utilisé
mais je croyais que si on déclare une variable en dehors d'un Sub (comme je l'ai fait) et qu'on change la valeur avec un Bouton par exemple alors la dernière valeur enregistré et celle qui a été modifié
Par exemple :
Dim Variable As Boolean = False
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Résultat =true
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
If Variable =true Then
MsgBox("La valeur est : True")
Else
MsgBox("La valeur est : False")
End Sub


le message qui va être affiché est
"La valeur est : True"
peut-être que je n'ai pas bien compris
0
Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 656 > Karin.code Messages postés 183 Date d'inscription vendredi 2 septembre 2016 Statut Membre Dernière intervention 16 janvier 2018
Modifié par Whismeril le 31/12/2016 à 13:48
Ceci devrait fonctionner, mais tes deux codes ne sont pas dans la même classe, voir mon premier exemple et le développement de VB95.

Par contre là encore tu utilises un accent, et ça c'est interdit.
Il y a beaucoup de choses conseillées, d'autres déconseillées, mais les accents c'est interdit.
0
vb95 Messages postés 3472 Date d'inscription samedi 11 janvier 2014 Statut Contributeur Dernière intervention 13 avril 2024 169
31 déc. 2016 à 00:57
bonsoir Karin.code

bonnes fêtes tout d'abord
Ensuite plusieurs points
1) Pourquoi les 2 Sub du BackGroundWorker ne sont pas dans la même class

Imports System.Net.Mail
Public Class Form1
Dim Compte As String
Dim Résultat As Boolean = False

Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
If ComboBox1.Text = "Gmail" Then 'le type de votre compte
Compte = "smtp.gmail.com"
End If
If ComboBox1.Text = "Hotmail" Then 'le type de votre compte
' etc ...................
End Sub
'End Class ' à enlever

Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
If Résultat = True Then
MessageBox.Show("Votre email a bien été envoyé", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information)
Else
MessageBox.Show("le message n'a pas été envoyé veuillez réessayer plus tard", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
End Sub

End Class


2)

If ComboBox1.Text = "Gmail" Then 'le type de votre compte
Compte = "smtp.gmail.com"

tu utilises 3 fois Combobox1.Text
Crées une variable String puis sers en toi

dim FournisseurMessagerie as string = ComboBox1.Text
If FournisseurMessagerie = "Gmail" Then 'le type de votre compte
Compte = "smtp.gmail.com"
' etc ........

Les contrôles ne servent qu'à l'affichage de données ! Créer les variables adéquates pour insérer dans le code leurs valeurs

3) Regarde dans le cours VB Net que l'on t'a suggéré à plusieurs reprises ! Tu verras à la rubrique sur les BackGroundWorker que l'on peut récupérer avec e.error dans BackgroundWorker1_RunWorkerCompleted le fait que le tâche en BackGround se soit déroulée correctement ou non ! De ce fait la variable Resultat devient inutile

4) Tout n'est pas forcement à mettre dans le BackGround !
L'envoi du mail ne concerne réellement que l'instruction

Dim Mail As New MailMessage()
Dim Smtp As New SmtpClient(Compte)
''If Not TextBoxFichier.Text = "" Then 'Chemin d'accès de la pièce jointe
' à supprimer la ligne en vert au dessus ( faire le test avant le BackGrounWorker;DoWork
Mail.Attachments.Add(New Attachment(TextBoxFichier.Text))
End If
Mail.From = New MailAddress(TextBoxEmail.Text) 'Votre email
Mail.To.Add(TextBoxEmailDestinateur.Text) 'email de celui a qui le message électronique sera envoyé
Mail.Subject = (TextBoxSujet.Text) 'Objet du message
Mail.Body = (TextBoxMessages.Text) 'Texte du message
Smtp.Port = ("587")
Smtp.Credentials = New System.Net.NetworkCredential(TextBoxEmail.Text, TextBoxMotdepasse.Text)
Smtp.EnableSsl = True
Try
Smtp.Send(Mail) ' l'envoi du mail est ici
Catch ex As Exception
End Try


5) Sers toi de With ........End With

Smtp.Port = ("587")
Smtp.Credentials = New System.Net.NetworkCredential(TextBoxEmail.Text, TextBoxMotdepasse.Text)
Smtp.EnableSsl = True


With Smtp
.Port = ("587")
.Credentials = New System.Net.NetworkCredential(TextBoxEmail.Text, TextBoxMotdepasse.Text)
.EnableSsl = True
End With

Tu n'écris qu'une fois le mot Smtp

bonne programmation et bon réveillon
0
Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 656
Modifié par Whismeril le 31/12/2016 à 11:09
Bonjour VB, je n'avais pas prêté attention au combobox, ça n'est pas l'objet de la question...

Une solution est de binder le contrôle à une collection d'une classe dédiée à la configuration, car dans le code le port est forcé à 587 et le SSL à true, mais le jour ou un des 3 comptes change de configuration ou si on veut ajouter un compte qui n'a pas le même port ou ne supporte pas SSL, ça va merder.
Voilà un exemple vite fait
la classe
Class ConfMail

  Public Sub New(ByVal LaDesignation As String, ByVal LeSmtp As String, ByVal LeMailEntrant As String, ByVal LePort As Integer, ByVal LeIsPop As Boolean, ByVal LeEnabledSSL As Boolean)
   Designation = LaDesignation
   Smtp = LeSmtp
   MailEntrant = LeMailEntrant
   Port = LePort
   IsPop = LeIsPop
   EnabledSSL = LeEnabledSSL
  End Sub

  'Avec veleurs par défaut
  Public Sub New(ByVal LaDesignation As String, ByVal LeSmtp As String)
   Me.New(LaDesignation,LeSmtp,"Pas renseigné",587,True,True)
  End Sub

  Public Property Designation() As String

  Public Property Smtp() As String

  Public Property MailEntrant() As String

  Public Property Port() As Integer

  Public Property IsPop() As Boolean

  Public Property EnabledSSL() As Boolean
 End Class


et comment binder
   Dim confsMails As New List(Of ConfMail)() From {New ConfMail("Gmail", "smtp.gmail.com"), New ConfMail("Hotmail", "smtp.live.com"), New ConfMail("Yahoo", "smtp.mail.yahoo.fr")}

   comboBox1.DataSource = confsMails
   comboBox1.DisplayMember = "Designation"


   Dim confChoisie As ConfMail = CType(comboBox1.SelectedItem, ConfMail)

Pour aller plus loin dans le binding, tu peux lire mon tuto.

Par contre, je n'avais pas fait attention que la variable Resultat à un accent. On ne mets jamais d'accents, de cédilles, de tildes etc.... à un nom quelconque en programmation, ces signes sont dépendants de la langues, il suffit que tu passes ton code à quelqu'un qui est configuré en anglais et ça bogue de partout...
0
Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 656 > Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024
31 déc. 2016 à 11:11
PS l'avantage c'est que la collection de configMail peut (doit) être issue d'une source extérieure (fichier de config, xml, json, csv, base de données...) et l'utilisateur peut gérer ses comptes sans tout te refaire compiler.
0
Karin.code Messages postés 183 Date d'inscription vendredi 2 septembre 2016 Statut Membre Dernière intervention 16 janvier 2018 2
Modifié par Karin.code le 31/12/2016 à 13:42
Bonjour VB95
Merci de m'avoir répondu
Bonnes fêtes à toi aussi
Pourquoi les 2 Sub du BackGroundWorker ne sont pas dans la même class
c'est vrai j'ai fait une fois quand j'ai copié le code partie par partie
tu utilises 3 fois Combobox1.Text
Crées une variable String puis sers en toi

tu me l'as dit tellement de fois désolé, je vais faire attention dès maintenant
je crois avoir corrigé les erreurs que tu a mentionné mais j'ai toujours une erreur qui s'affiche
"L'hôte SMTP n'a pas été spécifié."
Dim FournisseurMessagerie As String = Form1.ComboBox1.Text
Dim Mail As New MailMessage()
Dim Smtp As New SmtpClient(Compte)
Dim Compte As String
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
If FournisseurMessagerie = "Gmail" Then
Compte = "smtp.gmail.com"
End If
If FournisseurMessagerie = "Hotmail" Then
Compte = "smtp.live.com"
End If
If FournisseurMessagerie = "Yahoo" Then
Compte = "smtp.mail.yahoo.fr"
End If
If Not My.Settings.Fichier1 = "" Then
Mail.Attachments.Add(New Attachment(My.Settings.Fichier1))
End If
With Mail
.From = New MailAddress(My.Settings.Email)
.To.Add(My.Settings.Destinateur)
.Subject = (My.Settings.Sujet)
.Body = (My.Settings.Messages)
End With
With Smtp
.Port = ("587")
.Credentials = New System.Net.NetworkCredential(My.Settings.Email, My.Settings.MotdePasse)
.EnableSsl = True
End With
BackgroundWorker1.RunWorkerAsync()
End Sub
Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Smtp.Send(Mail)
End Sub
Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
MessageBox.Show("Votre email a bien été envoyé", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information)
End Sub
0
Karin.code Messages postés 183 Date d'inscription vendredi 2 septembre 2016 Statut Membre Dernière intervention 16 janvier 2018 2 > Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024
31 déc. 2016 à 13:59
Merci, Je vais lire ton tuto
c'est une bonne remarque, je croyais qu'il ne faut pas mettre d'accent juste pour les non des contrôles mais pas pour les variables, je ferai plus attention à l'avenir
0
vb95 Messages postés 3472 Date d'inscription samedi 11 janvier 2014 Statut Contributeur Dernière intervention 13 avril 2024 169 > Karin.code Messages postés 183 Date d'inscription vendredi 2 septembre 2016 Statut Membre Dernière intervention 16 janvier 2018
31 déc. 2016 à 14:10
Bonjour Whismeril et Karin.code

Toujours aussi pro et pertinent dans tes conseils Whismeril ! Bravo et bon réveillon

Karin.code : tu définis la valeur de Smtp
Dim Smtp As New SmtpClient(Compte)
avant d'avoir donné une valeur adéquate à la variable compte
De plus tu te sers de la variable compte avant de l'avoir dimensionnée avec Dim

Dim Smtp As New SmtpClient(Compte)
Dim Compte As String


Gères aussi l'erreur pendant le background

Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
If (e.Error Is Nothing) = True Then
MessageBox.Show("Votre email a bien été envoyé", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information)
Else
MessageBox.Show("Erruer durant l'envoi du mail", "Information", MessageBoxButtons.OK, MessageBoxIcon.Warning)
End if
End Sub

Sur ce bon réveillon aussi à toi
0
Karin.code Messages postés 183 Date d'inscription vendredi 2 septembre 2016 Statut Membre Dernière intervention 16 janvier 2018 2
3 janv. 2017 à 09:45
Bonjour Vb95 et Whismeril
Merci pour vos conseils et votre aide
0
Rejoignez-nous