Erreur Thread [VB.NET]

Erreur Thread [VB.NET]

a marqué ce sujet comme résolu.
Auteur du sujet

Bonjour, suite à plusieurs de mes anciens poste sur openclassrooms sur ce sujet qui viennent d’être fermer car personne n’a compris ce que je voulais et l’on mal interprétez, je viens vers vous BIEN formuler mon problème.

Lorsque j’envoie un mail en VB.NET, la form ce fige pendant un petit moment. Et donc question était, comment éviter celà ?

Une personne ayant compris m’a demande m’a répondu qu’il fallait que je fasse un Thread de mon envoie de mail. J’ai donc fait des recherches et procéder comme suit:

Lors de l’appuis sur un boutton:

Dim Thread1 As New Threading.Thread(Sub() sendMail())
Thread1.Start()
Dans mon sendMail() :
 
Dim mail As New MailMessage
Dim SMTP As New SmtpClient
 
If ComboBox1.SelectedItem = ComboBox1.Items(0) Then
    SMTP = New SmtpClient("smtp.gmail.com")
    SMTP.Port = "587"
End If
 
mail.From = New MailAddress(TextBox1.Text) ' De
mail.To.Add(TextBox3.Text)                 ' Pour
mail.Subject = TextBox5.Text
mail.Body = RichTextBox1.Text
 
SMTP.Credentials = New System.Net.NetworkCredential(TextBox1.Text, TextBox2.Text)
SMTP.EnableSsl = True
 
SMTP.Send(mail)

Mais j’ai une erreur qui est là suivante:

 << System.InvalidOperationException: Opération inter-threads non valide: le contôle 'ComboBox1' a fait l'objet d'un accès à partir d'un thread autre que celui sur lequel il a été créé.

           à System.Windows.Forms.Control.get_Handle()

           à System.Windows.Forms.ComboxBox.get_SelectedIndex()

           à System.Windows.Forms.ComboxBox.get_SelectedItem()

           à MonProject.MonProject.sendMail() dans

           C:\Users\LG\Documents\Visual Studio 2010\Projects\System Fail\System Fail\mailSendLogiciel\main.vb:ligne 134>>

Alors comment résoudre ce problème ? Et comme retirer le léger freeze ?

Merci

Édité par LeGeek57510

+0 -0

Le message d’erreur te dit clairement ce qui ne va pas :

System.InvalidOperationException: Opération inter-threads non valide: le contôle 'ComboBox1' a fait l’objet d’un accès à partir d’un thread autre que celui sur lequel il a été créé.

J’en déduis que dans un thread, on ne peut pas utiliser les différents controles de la fenêtre. Donc tu dois passer par des paramètres, ou à défaut, par des variables globales.

+0 -0
Auteur du sujet

Le message d’erreur te dit clairement ce qui ne va pas :

System.InvalidOperationException: Opération inter-threads non valide: le contôle 'ComboBox1' a fait l’objet d’un accès à partir d’un thread autre que celui sur lequel il a été créé.

J’en déduis que dans un thread, on ne peut pas utiliser les différents controles de la fenêtre. Donc tu dois passer par des paramètres, ou à défaut, par des variables globales.

elegance

D’accord mais comme dit, comment faire sa ? J’ai aussi lus quelque part qu’il fallait l’invoke et que c’était sans doute de la que venais le problème. Mais je n’en n’ai pas la moindre idée de comment faire sa. Même avec recherche internet.

Au passage, j’écris ce texte avec quelle police d’écriture car je l’aime beaucoup :lol:

+0 -0

Pour une meilleure lecture :

Dim Thread1 As New Threading.Thread(Sub() sendMail())
Thread1.Start()
Dans mon sendMail() :
 
Dim mail As New MailMessage
Dim SMTP As New SmtpClient
 
If ComboBox1.SelectedItem = ComboBox1.Items(0) Then
    SMTP = New SmtpClient("smtp.gmail.com")
    SMTP.Port = "587"
End If
 
mail.From = New MailAddress(TextBox1.Text) ' De
mail.To.Add(TextBox3.Text)                 ' Pour
mail.Subject = TextBox5.Text
mail.Body = RichTextBox1.Text
 
SMTP.Credentials = New System.Net.NetworkCredential(TextBox1.Text, TextBox2.Text)
SMTP.EnableSsl = True
 
SMTP.Send(mail)

Comment faire :

Regarde ici :

https://msdn.microsoft.com/fr-fr/library/6x4c42hc(v=vs.110).aspx

Imports System.Threading

Public Class Work
    Shared Sub Main()
        ' Start a thread that calls a parameterized static method.
        Dim newThread As New Thread(AddressOf Work.DoWork)
        newThread.Start(42)

        ' Start a thread that calls a parameterized instance method.
        Dim w As New Work()
        newThread = New Thread(AddressOf w.DoMoreWork)
        newThread.Start("The answer.")
    End Sub

    Public Shared Sub DoWork(ByVal data As Object)
        Console.WriteLine("Static thread procedure. Data='{0}'",
                          data)
    End Sub

    Public Sub DoMoreWork(ByVal data As Object) 
        Console.WriteLine("Instance thread procedure. Data='{0}'",
                          data)
    End Sub
End Class
' This example displays output like the following:
'    Static thread procedure. Data='42'
'    Instance thread procedure. Data='The answer.'
+1 -0
Auteur du sujet

Je comprend pas. Je suis allez voir et il y avait marqué "Il faut faire un invokerequired et si sa retourne false c’est bon, on peut appeler le thread." Donc c’est ce que j’ai fait mais toujours le même problème. Ce que j’ai essayer:

Dim Thread1 As New Thread(Sub() sendMailYesSpammer())
MsgBox(ComboBox1.InvokeRequired)
Thread1.Start()

Mais je pense que c’est moi qui m’y suis mal pris.

+0 -0
Auteur du sujet

J’ai pas eu le temps de faire l’édit mais j’ai trouver ! Action sur le bouton:

Dim Thread1 As New Thread(Sub() sendMail())
Thread1.IsBackground = True
Thread1.Start()

Et dans le sendMail():

Invoke(New MethodInvoker(Sub()

                                         Try
                                             Dim mail As New MailMessage
                                             Dim SMTP As New SmtpClient


                                             If ComboBox1.SelectedItem = ComboBox1.Items(0) Then
                                                 SMTP = New SmtpClient("smtp.gmail.com")
                                                 SMTP.Port = "587"
                                             End If

                                             mail.From = New MailAddress(TextBox1.Text) ' De
                                             mail.To.Add(TextBox3.Text)                 ' Pour
                                             mail.Subject = TextBox5.Text
                                             mail.Body = RichTextBox1.Text

                                             If Not TextBox7.Text = "" Then
                                                 Try
                                                     Dim mailAtt = New Net.Mail.Attachment(TextBox7.Text)
                                                     mail.Attachments.Add(mailAtt)
                                                 Catch ex As Exception
                                                     MessageBox.Show("Erreur, " & ex.ToString, "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Error)
                                                 End Try
                                             End If

                                             SMTP.Credentials = New System.Net.NetworkCredential(TextBox1.Text, TextBox2.Text)
                                             SMTP.EnableSsl = True

                                             SMTP.Send(mail)

                                             Me.Refresh()
                                         Catch ex As Exception
                                             MessageBox.Show("Erreur, " & ex.ToString, "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Error)
                                         End Try
                                     End Sub))

Conclusion: Le bug n’est plus la ! Mais le freeze est l’es-toujours. o_O

Édité par LeGeek57510

+0 -0
Auteur du sujet

Quand je dit "freeze" je veut dire que le légers fige est toujours là pendant 1 ou 2 secondes. Et pendant ce moment je ne peut rien faire sur la form comme la déplacer ou même appuyer sur un bouton. Alors comment savoir qu’elle est la ligne qui me fait figer ma form ?

+0 -0

Pour savoir quelle ligne provoque le freeze, tu peux y aller par tatonnement. Tu mets en commentaire par exemple les 10 dernières lignes de ton code, et tu testes. Bien entendu, l’envoi de mail ne marchera plus, mais ça te permettra d’isoler la portion de code qui est en cause.

Essaie déjà de mettre en commentaire juste la ligne Me.refresh(), pour voir ce que ça change.

+1 -0

Et Dim Thread1 As New Thread(AddressOf sendMail) ?

Un machin comme ça peut etre : Me.BeginInvoke https://stackoverflow.com/a/25757052/

OU : https://docs.microsoft.com/en-us/dotnet/api/system.componentmodel.backgroundworker?redirectedfrom=MSDN&view=netframework-4.7.2

Édité par A-312

+0 -0
Auteur du sujet

Et Dim Thread1 As New Thread(AddressOf sendMail) ?

Un machin comme ça peut etre : Me.BeginInvoke https://stackoverflow.com/a/25757052/

OU : https://docs.microsoft.com/en-us/dotnet/api/system.componentmodel.backgroundworker?redirectedfrom=MSDN&view=netframework-4.7.2

A-312

Toujours rien, même avec sa:

Dim Thread1Start As New ThreadStart(AddressOf sendMail)
Dim Thread1 As New Thread(Thread1Start)
Thread1.IsBackground = True
Thread1.Start()

Édité par LeGeek57510

+0 -0
Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte