IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Silverlight Discussion :

Développement asynchrone événementiel


Sujet :

Silverlight

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé Avatar de anthyme
    Homme Profil pro
    Inscrit en
    Mars 2004
    Messages
    1 559
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2004
    Messages : 1 559
    Par défaut Développement asynchrone événementiel
    Bonjour,

    j'essaie d'implémenter du développement asynchrone dans mon appli silverlight et après avoir lu la msdn je dois dire que j'ai plus de nœuds au cerveau qu'avant ... donc je viens vous demander conseil

    Dans le principe je veux effectuer ceci :

    J'ai des objets distribué via un service WCF mais mon appli est assez persistante et donc certaines parties de l'application peuvent avoir à nouveau besoin de ces objets donc pour éviter de les télécharger a nouveau j'ai mis une couche de synchronisation (ou plus simplement cache) devant mon service et j'appel cette couche au lieu d'appeler le service.
    Sauf que comme le service est asynchrone je doit faire cette couche de manière asynchrone aussi et la je galère pas mal ...

    En gros niveau code métier c'est très simple : si l'objet est dans une liste je lève un événement "completed" qui contient l'objet, si il est pas la je fais appel au service qui va lever l'événement completed du service, que j'utilise pour lever mon événement completed.

    Si j'ai bien tout compris il me faut 3 méthodes (et un événement) :
    methodAsync : appelé par le client et fait un BeginInvoke sur un objet AsyncCallback créé a partir de la méthode métier.
    method : la méthode métier (récupère l'objet dans le cache ou appel le service) qui prend un argument un IAsyncResult dans lequel je met une variable input (long ID). A priori exécute dans un autre thread
    methodCallback : la méthode exécute dans le thread principal (je crois) qui va s'occuper de lever l'événement indiquant que c'est fini contenant l'objet UNIQUEMENT si l'objet était bien présent dans le cache.

    Mon problème vient du fait que je passe l'objet IAsyncResult ente la méthode et le callback (c'est donc la seul "source d information"), mais un IAsyncResult est read only donc je ne peux pas y mettre mon objet dedans.

    En gros ma question est celle ci : Comment "passer" de la donné dans le callback ? Le but est de faire une archi proche des clients de service WCF

    Après j'aurai pu lever l'événement dans la méthode principal mais je pense qu'elle n'aurai pas été dans le bon thread.

    Comme du code vaut mieux qu'un long discours en voici un peu :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
     
        public abstract class SynchronizationManager<T> where T : IEntityUpdatable<T>
        {
            protected IGameController Controller;
            protected Dictionary<long,T> Entities;
     
            public void GetAsync(long id)
            {
                AsyncCallback async = new AsyncCallback(Get);
     
                async.BeginInvoke(new AsyncResult { AsyncState = id }, new AsyncCallback(GetEnded), id + 1);
            }
     
            private void Get(IAsyncResult ar)
            {
                long id = (long)ar.AsyncState;
                lock (Entities)
                {
                    if (Entities.ContainsKey(id))
                    {
                        //FAIL
                        //ar.AsyncState = Entities[id];
                        //ar.IsCompleted = true;
                    }
                    else
                    {
                        //FAIL
                        //ar.IsCompleted = false;
                        ServiceGet(id);
                    }
                }
            }
     
            private void GetEnded(IAsyncResult ar)
            {
                if (ar.IsCompleted)
                    OnGetCompleted((T)ar.AsyncState);
            }
     
            public event EventHandler<T> GetCompleted;
     
            protected void OnGetCompleted(T obj)
            {
                if (GetCompleted != null)
                    GetCompleted(this, obj);
            }
     
            public T Update(T obj)
            {
                if (Entities.ContainsKey(obj.ID))
                {
                    if (Entities[obj.ID].LocalUpdateDate < obj.LocalUpdateDate)
                    {
                        Entities[obj.ID].Update(obj);
                    }
                }
                else
                    Entities.Add(obj.ID, obj);
            }
     
            public abstract T ServiceGet(long id);
    Voila c'est un peu long désolé

    Si vous avez une solution plus efficace pour faire du cache sur les service je suis pas contre mais si je pouvais tout de même avoir des explications sur la programmation asynchrone ca serai top

    merci d'avance

  2. #2
    Membre éclairé
    Inscrit en
    Mai 2008
    Messages
    49
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 49
    Par défaut
    Si tu ne veux pas avoir à re-télécharger tes objets provenant du service WCF, je suppose que ton cache est géré dans le Silverlight(coté client)?.

    Si oui, pourquoi ne pas charger les objets du cache de façon synchrone puisque si le cache contient l'objet désiré tout est ok.

    Le mode asynchrone va surtout servir à ne pas bloquer l'interface car tu ne sais pas exactement quand le service WCF va te répondre. Alors que du coté de cache (client), s'il a l'objet désiré, il n'y a pas de temps de latence.

  3. #3
    Membre éprouvé Avatar de anthyme
    Homme Profil pro
    Inscrit en
    Mars 2004
    Messages
    1 559
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2004
    Messages : 1 559
    Par défaut
    Citation Envoyé par 28dev Voir le message
    Si tu ne veux pas avoir à re-télécharger tes objets provenant du service WCF, je suppose que ton cache est géré dans le Silverlight(coté client)?.

    Si oui, pourquoi ne pas charger les objets du cache de façon synchrone puisque si le cache contient l'objet désiré tout est ok.

    Le mode asynchrone va surtout servir à ne pas bloquer l'interface car tu ne sais pas exactement quand le service WCF va te répondre. Alors que du coté de cache (client), s'il a l'objet désiré, il n'y a pas de temps de latence.
    Mais justement je ne peux pas le faire de manière synchrone.
    Certe si il est déjà présent ça va je le renvoie direct mais si il ne l'ai pas : il va falloir que j'aille le chercher quand même et cela seulement de manière asynchrone ... et comme la partie qui demande l'objet doit le faire d'une façon unique (sans forcement savoir si c un objet "frai" ou non) et bien je suis obliger de le faire en async "dans le cas où" il y aurai besoin de faire appel au service.

    Merci de m'avoir lu et répondu en tout cas

  4. #4
    Membre éprouvé Avatar de anthyme
    Homme Profil pro
    Inscrit en
    Mars 2004
    Messages
    1 559
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2004
    Messages : 1 559
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    AsyncCallback async = new AsyncCallback(Get);
    async.BeginInvoke([...]);
    La 2eme ligne lève une exception :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    An exception of type 'System.NotSupportedException' occurred in Omega.UI but was not handled in user code
     
    Additional information: Specified method is not supported.
    qu'est ce que c'est que ce truc ? on ne peut pas faire d'asynchrone en silverlight ????

Discussions similaires

  1. Réponses: 0
    Dernier message: 09/10/2014, 11h37
  2. Réponses: 34
    Dernier message: 24/12/2013, 13h58

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo