2013-04-23 60 views
2

我正在構建設備模擬器。當它啓動時,它需要一些時間才能初始化。這將通過開啓並立即進入「初始化」狀態而在邏輯上表示,並且在一段時間後進入「就緒」狀態。如何在不阻擋UI的情況下向WPF程序添加延遲

我正在使用MVVM,所以ViewModel現在將代表所有的設備邏輯。每個可能的狀態都有一個數據查詢樣式,可以由View查看。如果我只是在構建視圖模型時設置狀態,視圖將呈現正確的外觀。

我想要做的是創建一個「超時狀態」,即當發生某些事件(啓動應用程序,單擊某個按鈕)時,設備進入一個固定時間的狀態,然後回退到「就緒」或「空閒」狀態。

我想過使用睡眠,但睡眠阻止用戶界面(所以他們說)。所以我想使用線程,但我不知道如何去做。這是我這麼遠:

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

首先具有一個屬性(的getter/setter)睡眠/異步操作被認爲是不好的做法

嘗試以此爲睡眠的替代品,而不會阻塞UI線程:

創建一個函數來設置EstadoEstados.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(); 
} 

現在每當你想改變setter時調用這個函數將會立即將狀態設置爲「Intiialising」並且在給定的milliSeconds切換到Initialised狀態之後。

+0

我與.NET 4.0在這裏,所以我認爲'async'不可用,是不是? – heltonbiker 2013-04-23 19:18:32

+0

@heltonbiker它不在.net4 :(你可以使用我剛剛添加的替代方法,它應該可以正常工作.net4 – Viv 2013-04-23 19:19:39

+0

此外,如果我嘗試在初始化過程運行時「獲取」設備狀態,返回'Estados.WirelessProcurando' – heltonbiker 2013-04-23 19:20:18

相關問題