silverlight. Wait end async method in sync method
I've got strange issue. I want wait end async call at sync function call. At other projects I successfully use ResetEvents, but in sl it don't seem to be working.
//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;
}
This method isn't work too:( Help please. What's wrong?
The problem comes from the fact that in SL all service calls are made on the UI thread. So you have one method trying to sleep on the UI thread, waiting on a callback that has to happen on the UI thread.
It is impossible to create a truly synchronous call in SL. If you really want to work with things in an synchronous fashion take a look at Caliburn. He uses some cool co-routine patterns to simulate synchronous programming while leaving the actual service calls async.
Just as:-
even * odd = even
so also:
async * sync = async.
You are attempting to make async * sync = sync
and that is what is tripping you up. As soon as you add an asynchronous operation to a sequence the whole sequence becomes asynchronous. If you can get your outer SaveValue
operation to accept that it is asynchronous then things can work better.
Since the code will follow quite divergent paths depending on whether encrypted is true or not then there really ought to be two versions of SaveValue
.
For example:-
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
}
In this version the first SaveValue is synchronous whereas the second which does the encrypting is asynchronous and will call the doneCallback when complete. This call back allows this asynchronous version of SaveValue
to participate in a further sequence of asynchronous operations.
精彩评论