-
Notifications
You must be signed in to change notification settings - Fork 2
AsyncViewModelBase
The AsyncViewModelBase builds upon the VMB and extends its with several methods to start actions as new Tasks. The AVMB contains also a list of all currently running tasks "Tasks" and a property that indicates if any task is currently running IsWorking and IsNotWorking. It allows to start an Task by simply calling "SimpleWork" or if its an async/await operation "SimpleWorkAsync". With that it is super easy to separate long running tasks from a ViewModel action (such as an execution from an UICommand) and avoid the blocking of the whole application while updating the UI with the IsWorking property of the changes.
Example:
public class MainWindowViewModel : AsyncViewModelBase
{
public MainWindowViewModel()
{
AnyCommand = new DelegateCommand.DelegateCommand(AnyExecute);
}
public DelegateCommand.DelegateCommand AnyCommand { get; private set; }
private void AnyExecute(object sender)
{
//when starting a new Task the AsyncViewModelBase.IsWorking property of the instance is set as long as there are any tasks
SimpleWork(() =>
{
//this code will be executed in a new Task created by the AsyncViewModelBaseOptions.TaskFactory
//and added to the AsyncViewModelBaseOptions.TaskScheduler
});
//for async/await
SimpleWorkAsync(async () =>
{
//this code will be executed in a new Task created by the AsyncViewModelBaseOptions.TaskFactory
//and added to the AsyncViewModelBaseOptions.TaskScheduler
await Task.CompletedTask;
});
}
}
All exceptions that are thrown in any of the Tasks created by AVMB should be handled with the OnTaskException method. Otherwise if not handled, they will be bubbled into the callers Thread and will be rethrown there!
protected override bool OnTaskException(Exception exception)
{
//handle your exception here like
Console.WriteLine(exception);
return base.OnTaskException(exception);
}
You can also schedule multiple tasks and await them by using the BeginScope method. This method returns an AwaitMultiple object that gathers all Tasks running until it is disposed. You can call GetAwaiter to await all currently running tasks.
//this creates a new scope for awaiting multiple tasks
using (var scope = BeginScope())
{
for (int i = 0; i < 10; i++)
{
SimpleWork(() =>
{
//this code will be executed in a new Task created by the AsyncViewModelBaseOptions.TaskFactory
//and added to the AsyncViewModelBaseOptions.TaskScheduler
});
}
scope.GetAwaiter().GetAwaiter().GetResult();
}