我正在构建设备模拟器。当它启动时,它需要一些时间来初始化。这将通过打开并立即进入“初始化”状态进行逻辑表示,并在一段时间后进入“就绪”状态。
我正在使用MVVM,因此ViewModel现在将代表所有设备逻辑。每个可能的状态都具有由视图呈现的数据触发样式。如果我只是在构建视图模型时设置状态,则视图将以正确的外观呈现。
我想要做的是创建一个“超时状态”,也就是说,当某个事件发生时(启动应用程序,单击某个按钮),设备进入状态一段固定时间,然后再回到“准备好”或“闲置”状态。
我考虑过使用Sleep,但是睡眠阻止了UI(所以他们说)。所以我考虑使用Threads,但我不知道该怎么做。这是我到目前为止所得到的:
using System.ComponentModel;
namespace EmuladorMiotool {
public class MiotoolViewModel : INotifyPropertyChanged {
Estados _estado;
public Estados Estado {
get {
return _estado;
}
set {
_estado = value;
switch (_estado) {
case Estados.WirelessProcurando:
// WAIT FOR TWO SECONDS WITHOUT BLOCKING GUI
// It should look like the device is actually doing something
// (but not indeed, for now)
_estado = Estados.WirelessConectado;
break;
}
RaisePropertyChanged("Estado");
}
}
public MiotoolViewModel() {
// The constructor sets the initial state to "Searching"
Estado = Estados.WirelessProcurando;
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void RaisePropertyChanged(string propertyName) {
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
public enum Estados {
UsbOcioso,
UsbAquisitando,
UsbTransferindo,
WirelessNãoPareado,
WirelessPareado,
WirelessDesconectado,
WirelessProcurando,
WirelessConectado,
WirelessAquisitando,
DataLoggerOcioso,
DataLoggerAquisitando,
Erro,
Formatando
}
}
答案 0 :(得分:1)
首先在属性(getter / setter)中进行Sleep / Async操作被认为是不好的做法
尝试将其作为Sleep的替代品而不阻止UI线程:
创建一个将Estado
设置为Estados.WirelessProcurando
假设WirelessProcurando
表示初始化,WirelessConectado
表示已初始化
<强> .net45 强>:
private async Task SetWirelessProcurando(int milliSeconds) {
Estado = Estados.WirelessProcurando;
await Task.Delay(milliSeconds);
Estado = Estados.WirelessConectado;
}
我们让函数返回Task
vs void
的原因只是让调用者在此函数上需要await
,如果逻辑需要它
如果您无法使用await
:
private void SetWirelessProcurando(int milliSeconds) {
Estado = Estados.WirelessProcurando;
var tempTask = new Task
(
() => {
Thread.Sleep(milliSeconds);
System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() => Estado = Estados.WirelessConectado));
},
System.Threading.Tasks.TaskCreationOptions.LongRunning
);
tempTask.Start();
}
现在,只要您想更改设置器,就会立即调用此函数,并立即将状态设置为“Intiialising”,并在给定的milliSeconds
切换到Initialised
状态之后。