From the documentation I’ve realized that I can use Caliburn Micro’s coroutines for async operations. Out of the box and without extra technologies. So I’ve implemented the next code in my Windows Phone app:
public class SimpleViewModel : Screen
{
// ...
protected override void OnViewLoaded(object view)
{
base.OnViewLoaded(view);
Coroutine.BeginExecute(RunTask());
}
public IEnumerator<IResult> RunTask()
{
yield return new SimpleTask();
}
// ...
}
SimpleTask:
public class SimpleTask : IResult
{
public void Execute(ActionExecutionContext context)
{
Thread.Sleep(10000);
}
public event EventHandler<ResultCompletionEventArgs> Completed;
}
I’ve hoped that code in Execute method will run async. But this not happen. My UI-thread was blocked for 10 seconds.
Where I made a mistake? Or my assumption about async nature of coroutines was wrong?
I spent the whole day searching for and trying code samples to finally have something that works (i.e. async operations using Caliburn Coroutines that do not block the UI), so I allow myself to share it.
As far as I understand, Coroutines in Caliburn do not handle threads, they just provide an elegant way to have async execution and control code handled in one method. One has to use other tools such as BackgroundWorkers to process operations in background threads.
I found this link pretty interesting, for silverlight. The aim was to include the background worker in a class that wraps coroutine calls.
As I wanted it in WPF with slight differences, I ended up with this code sample that works on my machine:
Wrapping class:
And in one of my ViewModels, the following:
With this, when I click on the ProcessTask button, the UI is not frozen, and the computed results appear as soon as they are made available by the background worker process. The IsBusy state is not mandatory but shows how UI-related states can go into the async-oriented code.
Hope this will help another me!