2010-05-18 2 views
1

У меня странная проблема. Я хочу, чтобы ожидание асинхронного вызова выполнялось при вызове функции синхронизации. В других проектах я успешно использую ResetEvents, но в sl он, похоже, не работает.серебряный свет. Подождите, асинхронный метод по методу синхронизации

//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; 
    } 

Этот метод не работает слишком :(Помогите пожалуйста, что случилось

ответ

2

Проблема возникает из-за того, что в SL все служебные вызовы выполняются в потоке пользовательского интерфейса. Таким образом, у вас есть один метод, который пытается спать в потоке пользовательского интерфейса, ожидая обратного вызова, который должен произойти в потоке пользовательского интерфейса.

Невозможно создать по-настоящему синхронный вызов в SL. Если вы действительно хотите работать с вещами синхронно, взгляните на Caliburn. Он использует некоторые классные шаблоны совместного программирования для имитации синхронного программирования, оставив при этом фактические вызовы службы async.

0

Так же, как: -.?

даже * нечетное = четное

так же:

async * sync = async.

Вы пытаетесь сделать async * sync = sync, и это то, что вас отключает. Как только вы добавляете асинхронную операцию в последовательность, вся последовательность становится асинхронной. Если вы можете получить свою внешнюю операцию SaveValue, чтобы принять, что она асинхронна, тогда все может работать лучше.

Поскольку код будет следовать довольно разным путям в зависимости от того, является ли зашифрованное истинным или нет, тогда действительно должны быть две версии SaveValue.

Например: -

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 
} 

В этой версии первого SaveValue является синхронным, тогда как второй, который делает шифрования является асинхронным и будет вызывать doneCallback при завершении. Этот обратный вызов позволяет этой асинхронной версии SaveValue участвовать в дальнейшей последовательности асинхронных операций.

Смежные вопросы