2010-05-18 6 views
1

J'ai un problème étrange. Je veux attendre la fin de l'appel asynchrone à l'appel de la fonction de synchronisation. Sur d'autres projets, j'utilise avec succès ResetEvents, mais en sl il ne semble pas fonctionner.silverlight. Attendre la fin async méthode dans la méthode de synchronisation

//Sync call save some value in storage 
    public static void SaveValue(string key, object value, bool encrypted) 
    { 
     if (encrypted) 
     { 
      isEncrypting = true; 
      var Registrator = new RegistratorClient(); 
      Registrator.EncryptCompleted +=Registrator_EncryptCompleted; 
      Registrator.EncryptAsync(obj); //async call 
      while (isEncrypting) 
       Thread.Sleep(10); 
      return; 
     } 
     ... 
    } 
    static void Registrator_EncryptCompleted(object sender, EncryptCompletedEventArgs e) 
    { 
     if (String.IsNullOrEmpty(fieldToSave)) 
      return; 
     App Appvars = Application.Current as App; 
     if (Appvars.Settings.Contains(fieldToSave)) 
      Appvars.Settings[fieldToSave] = e.Result; 
     else 
      Appvars.Settings.Add(fieldToSave, e.Result); 
     isEncrypting = false; 
    } 

Cette méthode est fonctionne pas trop :(Aide s'il vous plaît Qu'est-ce qui ne va pas

Répondre

2

Le problème vient du fait que dans SL tous les appels de service sont effectués sur le thread UI. Donc, vous avez une méthode qui essaie de dormir sur le thread de l'interface utilisateur, en attendant un rappel qui doit se produire sur le thread de l'interface utilisateur.

Il est impossible de créer un appel véritablement synchrone dans SL. Si vous voulez vraiment travailler de manière synchrone, jetez un oeil au Caliburn. Il utilise des modèles de co-routine pour simuler la programmation synchrone tout en laissant les appels de service réels asynchrones.

0

Tout comme: -.?

même * impair = pair

donc aussi:

async * sync = asynchrone

Vous essayez de faire async * sync = sync et c'est ce qui vous fait trébucher. Dès que vous ajoutez une opération asynchrone à une séquence, la séquence entière devient asynchrone. Si vous pouvez obtenir votre opération SaveValue pour accepter qu'il est asynchrone, les choses peuvent mieux fonctionner.

Comme le code suivra des chemins assez divergents selon que le chiffrement est vrai ou non alors il devrait vraiment y avoir deux versions de SaveValue.

Par exemple: -

public static void SaveValue(string key, object value) 
{ 
    App Appvars = Application.Current as App; 
    if (Appvars.Settings.Contains(key)) 
     Appvars.Settings[key] = value; 
    else 
     Appvars.Settings.Add(key, value); 
} 

public static void SaveValue(string key, object value, Action doneCallback) 
{ 

    var Registrator = new RegistratorClient(); 
    Registrator.EncryptCompleted += (s, args) => 
    { 
     // Really should consider some exception handling here. 
     SaveValue(key, s.Result); 
     if (doneCallback != null) 
      doneCallback(); 
    } 
    Registrator.EncryptAsync(value); //async call 
} 

Dans cette version la première saveValue est synchrone alors que le second qui fait le cryptage est asynchrone et appellera le doneCallback lorsque vous avez terminé. Ce rappel permet à cette version asynchrone de SaveValue de participer à une autre séquence d'opérations asynchrones.

Questions connexes