Reputation: 433
I am creating PCL using MvvmCross. I am calling one method in Command which fetch data by calling web service. I want to do this data fetch operation asynchronously. How can I apply async and await to methods in Command ?
Any ideas?
Upvotes: 1
Views: 2203
Reputation: 456507
There are a couple of options.
1) You can implement the command with an async void
method/delegate. If you do this, I recommend you have the async void
method just await
a Task
from an async Task
method that contains the actual logic because async Task
methods are easier to unit test. Also, you'll need a try
/catch
for proper error handling.
2) You can have the command just start a method returning Task<T>
and expose the result of the operation as a property using NotifyTaskCompletion
from my AsyncEx library. This allows you to data bind to the result as well as errors. However, AsyncEx does not support all the platforms MvvmCross does (in particular, Windows Phone 7.0 and Xamarin.Mac).
Update - examples:
Using the first option:
public ICommand ContactSlodgeCommand
{
get
{
return new MvxCommand(async () =>
{
await ComposeEmailAsync("[email protected]", "About MvvmCross and the SQL Bits app", "I've got a question"));
}
}
}
Using the second option:
private INotifyTaskCompletion<MyResource> _resource;
public INotifyTaskCompletion<MyResource> Resource
{
get { return _resource; }
set { _resource = value; NotifyPropertyChanged(); }
}
public ICommand LoadResourceCommand
{
get
{
return new MvxCommand(() =>
{
Resource = NotifyTaskCompletion.Create(LoadResourceAsync());
}
}
}
Upvotes: 6
Reputation: 1152
You should do data-binding for that property by using databinding of mvvmcross and use async await or Task like @Stephen Cleary said
void FetchData(Action<T> callback)
{
Task.Run<T>(()=>{
return Service.GetDataSynchronous();
}).ContinueWith((data)=>{
callback(data);
});
}
public MvxCommand
{
get
{
return new MvxCommand(()=>{
FetchData((data)=>{
this.Property = data;
});
});
}
}
Upvotes: 0