Вопрос по thread-sleep, wpf, user-interface, inotifypropertychanged – Как добавить задержку в программу WPF без блокировки пользовательского интерфейса

2

Я создаю эмулятор устройства. Когда он запускается, требуется некоторое время для его инициализации. Это было бы логично представлено включением и немедленным переходом кИнициализация» состояние, и через некоторое время оно уходитГотовы" государство.

Я использую MVVM, поэтому ViewModel пока представляет всю логику устройства. Каждое из возможных состояний имеет стиль передачи данных, который будет отображаться представлением. Если я просто устанавливаю состояние при построении модели представления, представление отображается с правильным внешним видом.

Что я хочу сделать, это создатьсостояние тайм-аута "то есть, когда происходит какое-либо событие (запуск приложения, нажатие определенной кнопки), устройство переходит в состояние на фиксированное время, а затем возвращается к «готовы", или же "холостой ход» государство.

Я думал об использовании Sleep, но сон блокирует пользовательский интерфейс (так они говорят). Поэтому я думаю об использовании потоков, но я не уверен, как это сделать. Это то, что я получил до сих пор:

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

Ваш Ответ

1   ответ
1

использование операции Sleep / Async в свойстве (getter / setter) считается плохой практикой.

Попробуйте это в качестве замены для Sleep без блокировки потока пользовательского интерфейса:

Создать функцию для установкиEstado вEstados.WirelessProcurando

Если предположить,WirelessProcurando Средства инициализации иWirelessConectado означает инициализированный

.net45:

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

Причина, по которой у нас есть функция, возвращаетTask против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 state.I»

@heltonbiker нет, это не так .net4 :(. Вы можете использовать альтернативный метод, который я только что добавил, который должен хорошо работать для .net4 Viv
м с .NET 4.0 здесь, так что я думаю,async не доступно, верно? heltonbiker
Кроме того, если я попытаюсьget состояние устройства во время процесса инициализации должно возвращаться.Estados.WirelessProcurando heltonbiker
@heltonbiker I 'Мы обновили мой ответ, чтобы немедленно установить состояние WirelessProcurando при вызове, а затем после заданной задержки переключить состояние на WirelessConectado из потока основного пользовательского интерфейса. Viv
@heltonbiker Хорошо, я думал, что WirelessProcurando означает инициализированное состояние. В каком состоянии вы хотите перейти при инициализации (т.е. после задержки) Viv

Похожие вопросы