Caliburn Micro在构造函数中开始协同程序-破坏视图

本文关键字:程序 视图 Micro 构造函数 开始 Caliburn | 更新日期: 2023-09-27 18:03:26

我使用CM的视图模型第一方法,在这里我创建一个视图模型并立即激活它。在ViewModel的构造函数中,我使用以下方法启动一个协程:

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

我在我的视图中有一个繁忙指示器,并且我设置了busy属性(这是与繁忙指示器控件上的IsBusy属性绑定的双向属性)为true。当为true时,指示器显示;当为false时,隐藏。

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

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属性在协程最初执行时计数为0,然后在第一个yield return之后突然计数为1。我可能错了,但似乎有某种竞争条件正在CM连接视图,我设置属性。

我也试过将协程移动到OnViewLoaded事件,但仍然有同样的问题,考虑到前一段,这是奇怪的!

谢谢

Caliburn Micro在构造函数中开始协同程序-破坏视图

这是一个很好的例子,说明如何使用CM做繁忙指示。

那么从你的协程中你可以做:

[Import(RequiredCreationPolicy = CreationPolicy.Shared)]
public IBusyWatcher Busy { get; set; }
private IEnumerable<IResult> LoadData()
{
    using (Busy.GetTicket())
    {
     ...
    }
}

虽然您已经表示client.AsyncOp();client.AnotherAsyncOp();是异步的,但您没有显示实现,因此不清楚那里发生了什么。

这份原稿。Micro不会让一个操作异步,你仍然需要在你的IResult内做的工作,这样它就不会在UI线程上执行,从而阻塞你的BusyIndicator。

这里有一个很好的协程解释,特别是这张图,希望能让你更清楚你的协程是如何被框架执行的。