EF & Silverlight : DataContext.Load synchrone en VB.NEt
-
lundi 14 janvier 2013 12:11
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 FunctionVisual 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
- Déplacé Aurel BeraMicrosoft Contingent Staff, Owner lundi 14 janvier 2013 12:37 O T
Toutes les réponses
-
lundi 14 janvier 2013 12:11impossible de placer ce post ailleurs, le forum ne marche pas....
FB
-
lundi 14 janvier 2013 12:37Propriétaire
Bonjour
J'ai deplace votre thread dans le bon forum.
Cordialement,
-
lundi 14 janvier 2013 12:59
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".
- Marqué comme réponse Aurel BeraMicrosoft Contingent Staff, Owner lundi 28 janvier 2013 10:52
-
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
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".
- Marqué comme réponse Aurel BeraMicrosoft Contingent Staff, Owner lundi 28 janvier 2013 10:53
-
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
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 finiMalgré 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".
- Modifié Patrice ScribeMVP mercredi 16 janvier 2013 17:52
- Marqué comme réponse FrançoisBOSSANT mercredi 16 janvier 2013 18:19
- Non marqué comme réponse FrançoisBOSSANT jeudi 17 janvier 2013 14:20
-
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
- Modifié FrançoisBOSSANT jeudi 17 janvier 2013 14:44
-
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
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 SubLe 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
- Modifié FrançoisBOSSANT jeudi 17 janvier 2013 14:40
-
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
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()}- Modifié FrançoisBOSSANT jeudi 17 janvier 2013 22:23
-
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
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
- Modifié FrançoisBOSSANT mercredi 23 janvier 2013 11:35
-
mercredi 23 janvier 2013 12:29
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 FunctionPour 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".
- Modifié Patrice ScribeMVP mercredi 23 janvier 2013 12:46
-
mercredi 23 janvier 2013 12:53
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
- Modifié FrançoisBOSSANT mercredi 23 janvier 2013 13:05
-
mercredi 23 janvier 2013 13:03Oui 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".
- Modifié Patrice ScribeMVP mercredi 23 janvier 2013 13:03
-
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
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".
- Marqué comme réponse Aurel BeraMicrosoft Contingent Staff, Owner lundi 28 janvier 2013 10:53
-
lundi 28 janvier 2013 10:53Proprié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,

