2

デバイスエミュレータを構築しています。起動すると、初期化に時間がかかります。これは論理的には、電源を入れてすぐに「初期化」状態になり、しばらくすると「準備完了」状態になることで表されます。

私は MVVM を使用しているため、現時点では ViewModel がすべてのデバイス ロジックを表します。考えられる各状態には、ビューによってレンダリングされるデータトリガー スタイルがあります。ビューモデルを構築するときに状態を設定するだけで、ビューは正しい外観でレンダリングされます。

私がやりたいのは、「タイムアウト状態」を作成することです。つまり、何らかのイベントが発生すると (アプリケーションの起動、特定のボタンのクリック)、デバイスは一定時間状態になり、その後「準備完了」に戻ります」、または「アイドル」状態。

Sleep を使おうと思ったのですが、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
    }
}
4

1 に答える 1

1

まず、プロパティ(ゲッター/セッター)でスリープ/非同期操作を行うことは、悪い習慣と見なされます

UI スレッドをブロックせずに Sleep の代わりとしてこれを試してください。

設定する関数を作成EstadoするEstados.WirelessProcurando

WirelessProcurandoInitializing を意味し、Initialized を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();
}

セッターを変更したいときはいつでもこの関数を呼び出すと、すぐに状態が「初期化中」に設定され、指定されmilliSecondsた状態への切り替え後に設定されInitialisedます。

于 2013-04-23T19:03:14.467 に答える