Meilleure méthode pour envoi de données par POST

Signaler
Messages postés
33
Date d'inscription
lundi 19 juillet 2010
Statut
Membre
Dernière intervention
6 mars 2013
-
 Utilisateur anonyme -
Bonjour,

Dans mon programme j'ai besoin d'envoyer des données liées à l'utilisation sur un serveur, ce que je fais par requête POST sur un script PHP. Cependant il arrive que cette action soit un peu longue du coup pendant ce temps, le programme ne répond pas vraiment, il n'enregistre plus les données et de plus après il arrive que les données enregistrées soit fausses (pas d'enregistrement, enregistrement en double...). Tout cela m'embête et j'ai eu l'idée de mettre la procédure d'envoi dans un BackgroundWorker histoire que ça n'influence pas le programme principal. Deux questions : est ce que c'est la bonne méthode ET est ce que c'est normal que le programme continue à laguer un petit peu ?

Encore une question : j'aimerais modifier l'icône de notification quand j'envoie les données, de manière à que l'utilisateur sache quand les données sont envoyées, et quand c'est terminé, cependant :
[list]
[*]Si je demande au BackgroudWorker de modifier l'icône (et le curseur de la souris aussi), une exception est levée car je tente de faire une opération inter-threads
[*] Si je le fais dans le programme, l'icône est définie, mais comme le BackgroundWorker fait une tâche en parallèle, et que mon code ressemble à :
ChangerIcone(IconeEnvoi)
BackgroundWorker.RunWorkerASync
ChangerIcone(IconeNormale)
/list


Bah l'icône est redéfinir tout de suite en normale
Alors quelle est selon vous la solution à mon problème ?

Merci d'avance

Thomas

4 réponses


Bonjour,

Il manque des précisions et surtout les parties de code qui posent problème. De quelle façon fais-tu tes requêtes POST ?
Pour le multithreading, intéresse toi aux délégués.
Messages postés
33
Date d'inscription
lundi 19 juillet 2010
Statut
Membre
Dernière intervention
6 mars 2013

Salut
Pour le POST, j'utilise cette fonction :
    Public Function HttpPost(ByVal URI As String, ByVal Parameters As String) As String
        System.Net.ServicePointManager.Expect100Continue = False
        Dim req As HttpWebRequest = DirectCast(HttpWebRequest.Create(URI), HttpWebRequest)
        'req.Proxy = new WebProxy("127.0.0.1:8080");
        req.ContentType = "application/x-www-form-urlencoded"
        req.Method = "POST"
        req.Headers.Add("Cookie: PHPSESSID=72ee54199f05f4123f50f6cb7e0f0bfb")
        Dim bytes As Byte() = System.Text.Encoding.ASCII.GetBytes(Parameters)
        req.ContentLength = bytes.Length
        Dim os As System.IO.Stream = req.GetRequestStream()
        os.Write(bytes, 0, bytes.Length)
        os.Close()
        Dim resp As HttpWebResponse = Nothing
        Try
            resp = DirectCast(req.GetResponse(), HttpWebResponse)
        Catch ew As Exception
            Dim coucou As String = ew.Message
        End Try
        If resp Is Nothing Then
            Return Nothing
        End If
        Dim sr As New System.IO.StreamReader(resp.GetResponseStream())
        'MessageBox.Show("STATUSCODE = " + resp.StatusCode.ToString());
        Return sr.ReadToEnd().Trim()
    End Function

Après je l'appelle dans cette fonction :
    Sub EnvoyerDonnees()
        If Username = "" Then
            MsgBox("Avant d'envoyer les données sur Internet, veuillez vous identifier dans la configuration")
            Exit Sub
        End If
        If ConnexionInternet = False Then
            MsgBox("Vous n'êtes pas connecté à Internet. Pour réexécuter le test de connexion, rendez-vous dans les paramètres")
            Exit Sub
        End If
        Dim param = "&username=" & Username & "&clicsgauches=" & NbrClicsGauches & "&clicsdroits=" & NbrClicsDroits & "&clicsmilieu=" & NbrClicsMilieu & "&scrollshaut=" & NbrScrollsHaut & "&scrollsbas=" & NbrScrollsBas & "&touches=" & NbrTouches & "&temps=" & Temps
        Dim ResultatHttpPost = HttpPost(AdresseServeur & "upload.php", param)
        If ResultatHttpPost = "0" Then
            My.Computer.Registry.SetValue("HKEY_CURRENT_USER\Software\Citrik Digital Inc.\CitriClics", "TAE", AES_Encrypt(0, CryptKey))
            My.Computer.Registry.SetValue("HKEY_CURRENT_USER\Software\Citrik Digital Inc.\CitriClics", "CDAE", AES_Encrypt(0, CryptKey))
            My.Computer.Registry.SetValue("HKEY_CURRENT_USER\Software\Citrik Digital Inc.\CitriClics", "SHAE", AES_Encrypt(0, CryptKey))
            My.Computer.Registry.SetValue("HKEY_CURRENT_USER\Software\Citrik Digital Inc.\CitriClics", "SBAE", AES_Encrypt(0, CryptKey))
            My.Computer.Registry.SetValue("HKEY_CURRENT_USER\Software\Citrik Digital Inc.\CitriClics", "CMAE", AES_Encrypt(0, CryptKey))
            My.Computer.Registry.SetValue("HKEY_CURRENT_USER\Software\Citrik Digital Inc.\CitriClics", "CGAE", AES_Encrypt(0, CryptKey))
            NbrTouchesAE = 0
            NbrClicsAE = 0
            NbrClicsDroitsAE = 0
            NbrClicsGauchesAE = 0
            NbrClicsMilieuAE = 0
            NbrScrollsAE = 0
            NbrScrollsHautAE = 0
            NbrScrollsBasAE = 0
            SauverDonnees()
            Parametres.FaireLoad()
        Else
            MsgBox("Désolé, mais une erreur fatale est survenue (erreur : " & vbCrLf & ResultatHttpPost, vbCritical, "Erreur")
        End If
        Afficher()
    End Sub
Messages postés
33
Date d'inscription
lundi 19 juillet 2010
Statut
Membre
Dernière intervention
6 mars 2013

je ne vois pas vraiment le rapport entre mon problème et les délégués, à ce que j'ai pu en lire sur différents sites. Peux tu éclairer ma lanterne ?

le programme ne répond pas vraiment, il n'enregistre plus les données et de plus après il arrive que les données enregistrées soit fausses (pas d'enregistrement, enregistrement en double...).

1 / Un cookie de session en dur dans le code (obligatoirement faux) est à éviter.
2 / Ta requête POST est plutôt rudimentaire. (C'est juste une constatation, agent, version protocole, nature de la connexion etc... manquants)
3 / Tu devrais fermer ton flux (os.Close) un peu plus tard après la réponse du serveur.


une exception est levée car je tente de faire une opération inter-threads
[...]
je ne vois pas vraiment le rapport entre mon problème et les délégués, à ce que j'ai pu en lire sur différents sites.


Voici deux exemples à tester dans un projet winforms vierge.

Celui-ci qui ne fonctionne pas :
Public Class Form1
    Dim lblTest As New Label With {.Parent =  Me}
    Dim WithEvents bgw As New System.ComponentModel.BackgroundWorker

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        bgw.RunWorkerAsync()
    End Sub

    Private Sub bgw_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bgw.DoWork
        Threading.Thread.Sleep(5000)
        lblTest.Text = "blabla"
    End Sub
End Class


Voici maintenant le même code mais qui fonctionne grâce au délégué :
Public Class Form1
    Dim lblTest As New Label With {.Parent  = Me}
    Dim WithEvents bgw As New System.ComponentModel.BackgroundWorker

    Private Delegate Sub MonDelegue(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs)

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        bgw.RunWorkerAsync()
    End Sub

    Private Sub bgw_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bgw.DoWork
        If lblTest.InvokeRequired Then
            lblTest.Invoke(New MonDelegue(AddressOf bgw_DoWork), sender, e)
        Else
            Threading.Thread.Sleep(5000)
            lblTest.Text = "blabla"
        End If
    End Sub
End Class