我在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事件,但仍然存在同样的问题,考虑到前一段,这很奇怪!
由于
答案 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线程上执行它,从而阻塞你的BusyIndicator。
对于协同程序here有一个非常好的解释,特别是this diagram,它应该更清楚地说明你的协程如何被框架执行。