EF & Silverlight : DataContext.Load synchrone en VB.NEt

Traitée EF & Silverlight : DataContext.Load synchrone en VB.NEt

  • lundi 14 janvier 2013 12:11
     
      A du code

    Bonjour

    J'ai besoin d'implémenter un DataContext.Load synchrone en vb.net dans un site SILVERLIGHT

    App.Context.Load(Of V_Lst_Personnel_Module)(App.Context.GetV_Lst_Personnel_ModuleQuery)
            Dim ld = App.Context.Load(Of V_Lst_Personnel_Module)(App.Context.GetV_Lst_Personnel_ModuleQuery())
            ld.Completed += Function(s, a)
                                For Each dbResourceType As V_Lst_Personnel_Module In DirectCast(s, LoadOperation(Of V_Lst_Personnel_Module)).Entities
                                Next
                            End Function

    Visual studio me retourne l'erreur :

    'Public Event Completed(sender As Object, e As System.EventArgs)' est un événement.
    Il ne peut donc pas être appelé directement.
    Utilisez une instruction 'RaiseEvent' pour déclencher un événement.


    FB

Toutes les réponses

  • lundi 14 janvier 2013 12:11
     
     
    impossible de placer ce post ailleurs, le forum ne marche pas....

    FB

  • lundi 14 janvier 2013 12:37
    Propriétaire
     
     
  • lundi 14 janvier 2013 12:59
     
     Traitée

    Bonjour,

    En VB, c'est AddHandler pour ajouter un gestionnaire d'évènement ce qui explique sans doute l'erreur de syntaxe. Voir par exemple http://stackoverflow.com/questions/204801/how-to-declare-lambda-event-handlers-in-vb-net

    (accessoirement je dirais qu'à strictement parler cela reste de l'asynchrone, c'est juste la notation qui permet de coder le gestionnaire "en ligne")


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".

  • lundi 14 janvier 2013 13:52
     
     

    Merci Aurel pour le déplacement de poste et Merci Patrice pour la réponse.

    Ce qui vut dire qu'il est difficile de faire des lancement synchro?


    FB

  • lundi 14 janvier 2013 14:26
     
     Traitée

    Ce que je veux dire est que si on mets une 3ème ligne à la suite, cette 3ème ligne va être exécutée alors que l'appel à Completed ne l'a pas encore été (on ne fait que "définir" Completed, on n'attends absolument pas qu'il soit exécuté), donc pour moi, même corrigé, le code montré est toujours asynchrone.

    C'est aussi le cas pour beaucoup de fonctions dans les applications Windows Store que l'on peut voir d'une certaine façon comme le successeur de Silverlight, il est donc sans doute préférable de s'y habituer.

    La nouvelle syntaxe Await/Async permet de faciliter les opérations en permettant de garder des opérations asynchrones mais en facilitant leur expression sous une forme séquentielle.

    Voir peut-être du côté de http://10rem.net/blog/2012/05/22/using-async-and-await-in-silverlight-5-and-net-4-in-visual-studio-11-with-the-async-targeting-pack qui doit donner les éléments pour utiliser cette nouvelle syntaxe dans Silverlight...


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".

  • mercredi 16 janvier 2013 13:00
     
     

    J'ai du mal à comprendre la logique Await/Async

    Je dois être stupide :)


    FB

  • mercredi 16 janvier 2013 17:37
     
      A du code

    C'est juste un peu particulier comme nouveauté. Le problème avec les opérations asynchrones est que le code ne s'exécute plus en séquence et qu'il faut donc par exemple gérer un évènement ou une "callback"de fin (qui peut éventuellement relancer une autre opération asynchrone etc... et il devient rapidement difficile de suivre l'enchainement des opérations) ou attendre activement (en bloquant éventuellement plus ou moins l'interface utilisateur ce qui n'est sans doute pas une solution acceptable) etc...

    Await veux juste dire "attendre la fin de l'opération asynchrone avant de passer à la suite..." Cela permet de simplifier le code en écrivant de manière séquentielle ces opérations asynchrones par exemple sur : http://blogs.msdn.com/b/kylemc/archive/2010/11/02/using-the-visual-studio-async-ctp-with-ria-services.aspx (j'ai copié le code qui m'intéresse ci-dessous).

    Et donc on peut mettre l'indicateur d'activité à vrai puis :
    - avec le premier exemple lancer les opérations de chargement l'une après l'autre en attendant à chaque fois que la précédente se termine
    - ou même avec le deuxième exemple, les lancer en parallèle et attendre que toutes soient terminées
    - avant de tout simplement remettre l'indicateur d'activité à faux, le chargement étant maintenant fini

    Malgré que ces opérations soient asynchrones, on garde un code qui reste extrèmement clair et qui sera donc aussi plus facile à écrire. Ci-dessous le code et vous devriez donc avec l'extension await/async pouvoir obtenir un code semblable dans votre application RIA :

    private async void InitializeData()
        {
          this.busyIndicator.IsBusy = true;
    
          // Serial
          await this._context.Load(              this._context.GetRedEntitiesQuery()).AsTask();
          await this._context.Load(              this._context.GetGreenEntitiesQuery()).AsTask();
          await this._context.Load(              this._context.GetBlueEntitiesQuery()).AsTask();
    
          // Parallel
          await TaskEx.WhenAll(
            this._context.Load(this._context.GetRedEntitiesQuery()).AsTask(),
            this._context.Load(this._context.GetGreenEntitiesQuery()).AsTask(),
            this._context.Load(this._context.GetBlueEntitiesQuery()).AsTask()
            );
    
          this.busyIndicator.IsBusy = false;
        }
      }

    Je me suis peut-être enflammé ;-) Déjà on est quel version de VS ? Vous n'avez qu'un seul Load RIA à lancer ?


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".



  • mercredi 16 janvier 2013 18:19
     
     

    Je suis en VS 2012 Premium

    Pour l'instant j'ai un RIA mais, j'ai aussi des soucis avec (ça manque trop de souplesse à mon gout). Et je vais finalement passer par un Service WCF .

    Mais le problème restera équivalent vu que la aussi, l'exécution des méthode est asynchrone à priori.

    J'ai bien compris.

    Mon 1er Test n'avait pas marché, parce que je l'avait placé dans l'évènment click d'un bouton. Or un await impose de placer async dans la procédure appelante ce qui n'était pas possible.


    FB


  • mercredi 16 janvier 2013 19:21
     
     

    Pour revenir à RIA, y a t'il une possibilité d'utiliser RIA et un WCF Data service?

    RIA limite certaines fonctionalités de SQL Server (les fonctions et les procédures, ...) et de toute façon j'aurais plus de souplesse avec mes requetes avec un WCF Data service.


    FB

  • jeudi 17 janvier 2013 14:24
     
      A du code

    Zut...

    Je voulais faire un truc du style :

    Async Sub TraiteDownLoad()
            Dim client As New WebClient()
            Dim uri As New Uri(App.RepertoireModeleXLSProcessusEtape, UriKind.RelativeOrAbsolute)
    
            AddHandler client.OpenReadCompleted, AddressOf client_OpenReadCompleted
            AddHandler client.DownloadProgressChanged, AddressOf client_DownloadProgressChanged
            Await client.OpenReadAsync(uri)
        End Sub

    Le Async  provoque l'erreur : "Impossible de trouver tous les types requis pour le modificateur 'Async'. Vérifiez que vous ciblez la bonne version de .NET Framework et que vous n'avez pas oublié de référencer un assembly. "

    Le Await : Cette expression ne produit pas de valeur. 

    J'ai activé NUGet sur le projet mais ça marche pas...


    FB


  • jeudi 17 janvier 2013 15:00
     
     

    http://nuget.org/packages/Microsoft.CompilerServices.AsyncTargetingPack/1.0.0

    suffisait d'installer le package

    Microsoft.CompilerServices.AsyncTargetingPack

    ...


    FB

  • jeudi 17 janvier 2013 21:56
     
      A du code
     Private Sub Ld_Rep_Completed(sender As Object, e As EventArgs)
            Dim Ld As LoadOperation(Of V_Exp_Processus_Etape_ListeRepertoires) = DirectCast(sender, LoadOperation(Of V_Exp_Processus_Etape_ListeRepertoires))
            Dim s As Task(Of Boolean)
            If Ld.Entities.Count > 0 Then
    
    
                Dim uriFic As New Uri(App.RepertoireModeleXLSProcessusEtape & "/" & Ld.Entities(0).Repertoire & "/" & Ld.Entities(0).FichierEXCEL)
                s = FileExist(uriFic)
                If s.Result Then
                    SPDownload.Visibility = Windows.Visibility.Visible
                Else
                    SPDownload.Visibility = Windows.Visibility.Collapsed
                End If
            Else
                SPDownload.Visibility = Windows.Visibility.Collapsed
            End If
        End Sub
    
        Public Async Function FileExist(url As Uri) As Task(Of Boolean)
            Dim request As HttpWebRequest = HttpWebRequest.CreateHttp(url)
    
            Dim ws = Await request.GetResponseAsync()
    
            Return IIf(ws.ResponseUri.ToString() = "", False, True)
    
    
        End Function

    J'ai essayé ce code, et il ne fonctionne pas... Il se bloque au niveau du GetResponseAsync sans pour autant déclencher une erreur...

    En changeant le GetResponseAsync  ainsi j'obtiens l'erreur ci-dessous

    Dim ws = Await request.GetResponseAsync().ConfigureAwait(False)

    {System.Exception: Exception de HRESULT : 0x80000012" & vbCrLf & "   à System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)" & vbCrLf & "   à System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccess(Task task)" & vbCrLf & "   à System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)" & vbCrLf & "   à System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()" & vbCrLf & "   à SuiviProjet.ctrlDetailModule.VB$StateMachine_0_FileExist.MoveNext()}
  • mardi 22 janvier 2013 12:02
     
     

    Est-ce que l'on a ce même problème en faisant un test juste sur l'existance du fichier ? (c'est juste pour simplifier pour pouvoir reproduire/examiner le problème plus facile).

    C'est encore d'actualité pour la partie RIA (il me semblait dans un post précédant que vous alliez plutôt vers WCF ?)


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".

  • mardi 22 janvier 2013 18:54
     
     

    J'ai fait qq petits essais avec un service WCF compatible SL ou WebClient.DownloadStringTaskAsync sans voir de problème particulier.

    Egalement j'ai trouvé http://stackoverflow.com/questions/13520881/convert-async-function-that-trigger-an-event-to-awaitable-function-wp8 qui montre comment transformer un modèle de programmation async/evènement en async/await et ces classes sont bien disponibles dans Silverlight.

    Ah pas réagi sur le coup mais je pense que le problème n'a rien à voir. D'après https://connect.microsoft.com/VisualStudio/feedback/details/649543/ cela se produirait en cas de caractères invalides dans l'uri... Essayer peut-être voir la valeur de uri.


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".

  • mardi 22 janvier 2013 20:36
     
      A du code

    Vous avez été plus rapide que moi :) Je refais aussi des tests du coup pour me remettre dans le context de Jeudi dernier.

    1) Pour le download, je n'y arrive toujours pas... Le programme bloque par exemple sur l'url : http://localhost:65486/XLS/Achat/Grange_SA/Achat/FourniSSeur/Grange_SA_Achat_FourniSSeurProcessus_Etape.xls

    Qui je peux vous l'assurer pointe bien sur un fichier. D'ailleurs, en debug, lorsque je copie cet url dans un browser, il est bien telechargé...

    Quant aux caractères, il n'y a aucun espace, caractères spéciaux (sauf erreur)...

    Par contre mon idée était de placer les fichiers EXCEL dans un sous-répertoire du site web de la solution. C'est comme si il était inaccessible. J'ai essayé avec un nom de fichier simple et à la racine du site (meme problème). J'ai changer le mode d'authentification (meme problème)...

    Je suis reparti d'un projet vierge sur lequel j'ai juste appliqué le pack pour utiliser AsyncTargetingPack.Silverlight5. J'ai implémenté ce code :

    Imports System.Threading.Tasks Partial Public Class MainPage Inherits UserControl Dim request As HttpWebRequest Public Sub New() InitializeComponent() If FileExist(New Uri("http://localhost/Test/DB200_fr.pdf")).Result Then Me.Chk.Content = "Suis la !!!" Else Me.Chk.Content = "Po de fichier :(" End If End Sub

    Public Async Function FileExist(url As Uri) As Task(Of Boolean) request = HttpWebRequest.CreateHttp(url) Dim ws = Await request.GetResponseAsync Return IIf(ws.ResponseUri.ToString() = "", False, True) End Function End Class

    Aucun message d'erreur et le browser ne répond plus...

    2) Concernant le service WCF , je souhaite l'utiliser en complément du service RIA en espérant contourner des problèmes comme ci-dessus (mais à priori...)

    J'ai tenté en vain d'ajouter une référence à un service WCF sur un projet silverlight avec RIA activé. Le fichier ServiceReferences.ClientConfig reste vide et le projet ne compile plus.

    Par contre sans RIA ça marche.

    Vu la différences de comportement entre nos traitement, je me permets de repréciser que je travaille sous Win7x64, VS 2012 Premuim et Silverlight 5.

    Qu'entendez vous par compatible SL?


    FB







  • mercredi 23 janvier 2013 12:29
     
      A du code

    Pour le point 1 je proposerais comme point de départ (donc essentiellement j'ai ajouté un Await sur le FileExist pour que le résultat de cette fonction soit lui-même attendu de façon asynchrone) :

        Dim request As HttpWebRequest
        Private Async Sub MainPage_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
            If Await FileExistAsync(New Uri("http://localhost:65025/Test/DB200_fr.pdf")) Then
                'If Await FileExistAsync(New Uri("http://localhost:65025/TextFile1.txt")) Then
                Me.chk.Content = "Suis la !!!"
            Else
                Me.chk.Content = "Po de fichier :("
            End If
        End Sub
        Public Async Function FileExistAsync(url As Uri) As Task(Of Boolean)
            request = HttpWebRequest.CreateHttp(url)
            request.Method = "HEAD" ' Ne pas récupérer le contenu du fichier
            Dim ws As HttpWebResponse
            Try
                ws = CType(Await request.GetResponseAsync, HttpWebResponse)
            Catch ex As WebException
                If CType(ex.Response, HttpWebResponse).StatusCode = HttpStatusCode.NotFound Then
                    Return False
                End If
                ' TODO : à voir selon ce que l'on veut faire pour les autres états
                Throw
            End Try
            If ws.StatusCode <> HttpStatusCode.OK Then
                ' TODO : à voir selon ce que l'on veut faire pour les autres été
                Throw New NotImplementedException(ws.StatusCode & " à gérer ?")
            End If
            Return True
        End Function

    Pour 2) c'est pour être clair sur ce que j'ai testé (le "template" est "Service WCF compatible Silverlight". Je vais essayer de voir si les deux peuvent cohabiter (ou du coup ce n'est plus la peine si c'était pour contourner un problème qui serait résolu ?)

    Je pensais notamment que le lien que je mentionnais plus haut devrait permettre au pire de convertir le modèle async/evènement de RIA services vers le modèle async/await

    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".




  • mercredi 23 janvier 2013 12:53
     
      A du code

    1) Plantage sur le ligne :

    If Await FileExistAsync(New Uri("http://localhost:65025/Test/DB200_fr.pdf")) Then
     Je ne rentre même pas dans
    la fonction FileExistAsync.

    Erreur de sécurité.

       à System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       à System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccess(Task task)
       à System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
       à System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
       à SilverlightApplication2.MainPage.VB$StateMachine_0_MainPage_Loaded.MoveNext()

    2) "Service WCF compatible Silverlight" ? je ne le connaissais pas.

    => ça me donne des pistes sur la manière de mettre en forme le Web.Config (Cauchemard)^^
    => une partie est ajoutée avant la class :

    Imports System.ServiceModel
    Imports System.ServiceModel.Activation
    
    <ServiceContract(Namespace:="ServiceSuiviProjet")>
    <AspNetCompatibilityRequirements(RequirementsMode:=AspNetCompatibilityRequirementsMode.Allowed)>
    Public Class ....

    Mais otez moi d'un doute, si je souhaite exploiter un Service WCF, je le mets en référence du projet silverlight ou en référence de son projet Web?


    FB


  • mercredi 23 janvier 2013 13:03
     
     
    Oui j'avais donc mis le port en dur qui correspondait à mon site web du moment, remettez pour l'instant localhost (sans le n° de port) comme dans votre code original et cela devrait être ok (au final le mieux serait d'utiliser l'url d'où vient l'application Silverlight car tel que cela ne fonctionnera après déploiement).

    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".


  • mercredi 23 janvier 2013 14:58
     
     

    1) J'ai réussi à faire fonctionner votre code dans mon environnement.
    Il est impératif que les fichier soit dans le site web du projet Web sinon une erreur de sécurité bloque le code.
    Je vais donc essayer d'adapter le code à ma solution.

    2) si je souhaite exploiter un Service WCF, je le mets en référence du projet silverlight ou en référence de son projet Web?


    FB

  • mercredi 23 janvier 2013 17:38
     
     Traitée

    1) oui c'est le comportement par défaut mais on doit pouvoir le modifier (avec un fichier sur le site cible). cf http://msdn.microsoft.com/fr-fr/library/cc645032(v=vs.95).aspx  mais en anglais

    2) la référence est dans le client (ce qui va permettre de générer côté client tout ce qu'il faut pour accéder au serveur), le service lui-même est sur le serveur. Cela doit-être dans "ajouter une référence de service".


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".

  • lundi 28 janvier 2013 10:53
    Propriétaire
     
     

    Bonjour,

    Pouvons-nous considérer que vous avez résolu votre problème avec les scénarios proposés ? Dans l'affirmative, pourriez-vous partager avec nous la solution, afin que d'autres personnes avec le même problème puissent profiter de cette solution ?

    Désormais, nous marquons les solutions proposées. N'hésitez pas à revenir et supprimer la réponse marquée si la solution n’est pas correcte. Merci !

    Cordialement,


    Aurel BERA, Microsoft
    Microsoft propose ce service gratuitement, dans le but d'aider les utilisateurs et d'élargir les connaissances générales liées aux produits et technologies Microsoft. Ce contenu est fourni "tel quel" et il n'implique aucune responsabilité de la part de Microsoft.