Caliburn Micro在构造函数中开始coroutine - 打破视图?

时间:2011-07-22 15:01:21

标签: c# silverlight caliburn.micro

我在CM中使用View Model第一种方法,我创建一个ViewModel并在之后立即激活它。在ViewModel的构造函数中,我使用以下方法启动协程:

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

我的视图中有一个忙碌指示符,并且我将busy属性(即忙碌指示符控件上的IsWusy属性的TwoWay绑定)设置为true。如果为真,则指示器显示;如果是假的,它就是隐藏的。

所以我的协程看起来像这样:

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

问题似乎是IsBusy未正确传播到视图。有时指标甚至不显示。指示符将显示其他场合(最常见),但即使在IsBusy设置为false后也不会关闭。

我不相信这是一个繁忙的指标问题,因为这种情况会发生在各种其他属性中。例如,如果我设置了一个绑定到ListBox的SelectedItem的属性,那么将设​​置该属性,但ListBox不会将其显示为GUI中的SelectedItem。

最初执行协程时,Views属性的计数为零,然后在第一个yield return之后突然计数为1。我可能错了,但似乎有一种竞争条件正在进行,CM正在连接视图,我设置属性。

我也尝试将Coroutine移动到OnViewLoaded事件,但仍然存在同样的问题,考虑到前一段,这很奇怪!

由于

2 个答案:

答案 0 :(得分:2)

This是如何使用CM进行忙碌指示的一个很好的例子。

然后从你的Coroutines中你可以做到:

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

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

答案 1 :(得分:0)

虽然您已指出client.AsyncOp();client.AnotherAsyncOp();是异步的,但您没有显示实施情况,因此不清楚其中发生了什么。

Caliburn.Micro不会使操作异步,你仍然需要在IResult内进行工作,这样就不会在UI线程上执行它,从而阻塞你的BusyIndi​​cator。

对于协同程序here有一个非常好的解释,特别是this diagram,它应该更清楚地说明你的协程如何被框架执行。