2

我正在构建一个设备模拟器。当它启动时,它需要一些时间来初始化。这在逻辑上表现为打开并立即进入“初始化”状态,并在一段时间后进入“就绪”状态。

我正在使用 MVVM,因此 ViewModel 现在将代表所有设备逻辑。每个可能的状态都有一个由视图呈现的数据触发样式。如果我只是在构建视图模型时设置状态,则视图将以正确的外观呈现。

我要做的是创建一个“超时状态”,即当某些事件发生时(启动应用程序,点击某个按钮),设备进入一个固定时间的状态,然后回退到“准备就绪” ”,或“空闲”状态。

我考虑过使用睡眠,但睡眠会阻止 UI(他们说)。所以我考虑使用线程,但我不知道该怎么做。这是我到目前为止所得到的:

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
    }
}
4

1 回答 1

1

首先在属性(getter/setter)中进行睡眠/异步操作被认为是不好的做法

在不阻塞 UI 线程的情况下试试这个作为 Sleep 的替代品:

创建要设置Estado为的函数Estados.WirelessProcurando

假设WirelessProcurando意味着初始化并且WirelessConectado意味着初始化

.net45

private async Task SetWirelessProcurando(int milliSeconds) {
  Estado = Estados.WirelessProcurando;
  await Task.Delay(milliSeconds);
  Estado = Estados.WirelessConectado;
}

我们让函数返回一个Taskvs的原因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状态之后。

于 2013-04-23T19:03:14.467 回答