开发者

Caliburn Micro beginning coroutine in constructor - breaking the View?

I am using a View Model first approach with CM where I create a ViewModel and activate it immediately after. In the constructor of the ViewModel I am starting a coroutine using the method:

Coroutine.BeginExecute(Example().GetEnumerator());

I have a busy indicator in my views, and I set the busy property (that's TwoWay bound to the IsBusy property on t开发者_JAVA百科he busy indicator control) to true. When true, the indicator shows; when false, it's hidden.

So my coroutine would look something like this:

IsBusy = true;
var example = client.AsyncOp();
yield return example;
var exampletwo = client.AnotherAsyncOp();
yield return exampletwo;
IsBusy = false;

The issue appears to be IsBusy not propagating to the view correctly. There are occasions when the indicator won't even show. There are other occasions (the most common) where the indicator will show, but won't turn off even after IsBusy is set to false.

I don't believe this is a busy indicator issue as this happens with various other properties. If, for example, I set a property that's bound to a ListBox's SelectedItem, the property will be set, but the ListBox won't show it as its SelectedItem in the GUI.

The Views property has a count of zero when the coroutine is initially executed, and then suddenly has a count of 1 after the first yield return. I maybe wrong, but it seems like there's some kind of race condition going on where CM is hooking up the view, and me setting the properties.

I have also tried moving the Coroutine to the OnViewLoaded event, but that still has the same problems, which is curious considering the previous paragraph!

Thanks


This is an excellent example of how to do busy indicator with CM.

Then from your Coroutines you can do:

[Import(RequiredCreationPolicy = CreationPolicy.Shared)]
public IBusyWatcher Busy { get; set; }

private IEnumerable<IResult> LoadData()
{
    using (Busy.GetTicket())
    {
     ...
    }
}


Although you've indicated that client.AsyncOp(); and client.AnotherAsyncOp(); are async, you've not shown the implementation so it's not clear what's happening in there.

Caliburn.Micro won't make an operation async, you still need to do the work inside your IResult so that it is not executed on the UI thread and therefore blocking your BusyIndicator.

There's a really good explanation of coroutines here, in particular this diagram which should hopefully make it clearer how your coroutine gets executed by the framework.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜