Silverlight的。在同步方法中等待结束异步方法

时间:2010-05-18 07:09:40

标签: silverlight multithreading asynchronous

我有一个奇怪的问题。我想在同步函数调用等待结束异步调用。在其他项目中我成功使用了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 个答案:

答案 0 :(得分:2)

问题来自SL中所有服务调用都是在UI线程上进行的。所以你有一种方法试图在UI线程上休眠,等待必须在UI线程上发生的回调。

在SL中创建真正的同步调用是不可能的。如果您真的想以同步方式处理事物,请查看Caliburn。他使用一些很酷的协同例程模式来模拟同步编程,同时让实际的服务调用保持异步。

答案 1 :(得分: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的异步版本参与另一个异步操作序列。