我有一个奇怪的问题。我想在同步函数调用等待结束异步调用。在其他项目中我成功使用了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;
}
此方法也不起作用:(请帮助。出了什么问题?
答案 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
的异步版本参与另一个异步操作序列。