2014-09-03 138 views
-2

我開始異步/等待使用。我已經使用基於MVVM模式的WPF編寫了簡單的應用程序,但它並不像我預期的那樣工作。該程序的工作原理是沒有異步函數:在執行execute函數後,只有在循環函數結束後才凍結和解凍。等待/異步無法正常工作

請告訴我我錯了什麼。我會很感激任何反饋。 :)

這是我的modelview類。它繼承自wpf類,它包含標準wpf函數的定義,如OnPropertyChanged。

public class ModelView : wpf 
{ 
    string _state; 
    public string state { get { return _state; } set { _state = value; OnPropertyChanged("state"); } } 
    public DelegateCommand work { get; set; } 

    public ModelView() 
    { 
     state = "Program started"; 

     work=new DelegateCommand(_work); 
    } 

    async void _work(object parameter) 
    { 
     state = "Working..."; 

     int j=await loop(); 

     state = "Done: " + j; 
    } 

    async Task<int> loop() 
    { 
     int i; 
     for(i=0;i<1000000000;i++); 

     return i; 
    } 
} 
+9

你幾乎肯定會得到一個編譯器警告,因爲*告訴你*問題是什麼。 – 2014-09-03 11:47:46

+0

http:// stackoverflow。com/a/25078752/2530848 – 2014-09-03 11:52:28

回答

10

代碼中沒有異步部分。簡單地使用async關鍵字並非如此。使用Task.Run,而是如果你想卸載同步代碼到一個不同的線程:

async void _work(object parameter) 
{ 
    status = "Working..."; 
    int j=await Task.Run(() => loop()); 
    status = "Done: " + j; 
} 

int loop() 
{ 
    int i; 
    for(i=0;i<1000000000;i++); 
    return i; 
} 

如果你確實有一個異步操作,您可以使用來代替:

async void _work(object parameter) 
{ 
    status = "Working..."; 
    await Task.Delay(1000); 
    status = "Done: " + j; 
} 

指導:如果你的「異步」方法裏面沒有await,它不是異步的。

+0

代碼作品,謝謝你的迴應! – 2014-09-03 11:55:12

5

你沒有做任何異步。關鍵字async並不意味着「創建另一個線程」;它是相當複雜的,但基本上它允許代碼繼續工作另一個異步操作完成。好的例子包括異步數據庫訪問,文件訪問,網絡訪問等。它還可以包括通過線程和Task.Run的異步長時間運行操作。但是:你不是那麼做await沒有任何不完整的代碼 - 的代碼在主線程上運行。當從有不完整的東西時,它只安排了一個延續

引述編譯器(談論loop法):

警告此異步方法缺乏「等待」運營商和將同步運行。考慮使用'await'操作符來等待非阻塞API調用,或者'等待Task.Run(...)'在後臺線程上執行CPU綁定工作。

+0

感謝您的迴應,這是我不知道的! – 2014-09-03 11:54:50

+0

@RicoW關鍵點:'await'永遠不會創建線程;如果你正在等待的東西已經完成,它就會繼續;否則它會爲該「事物」添加一個延續,當* *完成時,它將從那裏繼續運行 – 2014-09-03 12:35:08

1

看起來問題是你的loop函數。即使您已聲明它爲async,但其中沒有await語句,您應該看到@Marc Gravell指出的編譯器警告。

該函數雖然大量循環迭代佔用UI線程會導致阻塞,但它會返回最終值。

所以你循環功能實際上是一個同步功能。假設你是爲了測試目的而做的,模擬async操作的好方法是使用Task.Delay。例如:

async Task<int> loop() 
{ 
    await Task.Delay(5000); 

    return 1; 
}