I want to wrap 3rd party function to Task to be able to await for finish the callback function. This is what I would like to achieve:
public MyClass MyProperty {
get
{
if (myProperty == null)
myProperty = LoadMyValue("1234");
return myProperty ;
}
set
{
myProperty = value;
}
}
public MyClass LoadMyValue(string id) {
return MyClassTools.LoadMyValue(id);
}
and in MyClassTools
static public MyClass LoadMyValue(string id) {
3rdPartyApi.Call(id, Callback);
// here I want to return Callback result
}
static MyClass Callback(3rdPartyResult result) {
return new MyClass(result);
}
How to use here Tasks and async/await to be able return Callback result directly from function LoadMyValue?
As Noseratio suggested, you can use TaskCompletionSource<T> to wrap the asynchronous API:
public static Task<3rdPartyResult> CallAsync(string id)
{
var tcs = new TaskCompletionSource<3rdPartyResult>();
3rdPartyApi.Call(id, result =>
{
if (result.Exception == null) // or whatever
tcs.TrySetResult(result);
else
tcs.TrySetException(result.Exception);
});
return tcs.Task;
}
You can then make LoadMyValue an asynchronous method:
static public async Task<MyClass> LoadMyValueAsync(string id)
{
return new MyClass(await CallAsync(id));
}
However, this will not help you return the value from your property. Properties cannot be asynchronous. In your case, it looks like you want an "asynchronous lazy" type of value, which you can do like this:
private readonly Lazy<Task<MyClass>> myProperty =
new Lazy<Task<MyClass>>(() => LoadMyValueAsync("1234");
public Lazy<Task<MyClass>> MyProperty
{
get { return myProperty; }
}
Note that I removed the setter since the semantics don't make sense for an asynchronously lazy-evaluated property.
You can then use the property like this:
MyClass value = await MyProperty.Value;
There are some types out there that can make the code slightly easier. E.g., Noseratio's type for callback wrapping, or Stephen Toub's AsyncLazy<T> (which is also a part of my AsyncEx library).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With