簡體   English   中英

等待/異步無法按預期工作

[英]Await/async doesn't work as expected

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

請告訴我我做錯了什么部分。 我很感激任何反饋。 :)

這是我的模型視圖類。 它繼承自 wpf 類,該類包含 OnPropertyChanged 等標准 wpf 函數的定義。

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

您的代碼中沒有異步部分。 簡單地使用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 ,則它不是異步的。

你沒有做任何異步的事情。 async關鍵字並不意味着“創建另一個線程”; 它相當復雜,但基本上它允許代碼另一個異步操作完成使用延續。 好的例子包括異步數據庫訪問、文件訪問、網絡訪問等。它還可以包括通過線程和Task.Run異步長時間運行的操作。 但是:你沒有那樣做 沒有不完整的await ——代碼只是在主線程上運行 它僅在有不完整的內容要繼續時才安排延續。

引用編譯器(談論loop方法):

警告此異步方法缺少“等待”運算符,將同步運行。 考慮使用 'await' 運算符來等待非阻塞 API 調用,或使用 'await Task.Run(...)' 在后台線程上執行 CPU 密集型工作。

看起來問題出在您的loop函數上。 即使您已將其聲明為async但其中沒有await語句,並且您應該收到編譯器警告,正如@Marc Gravell 指出的那樣。

該函數通過大量循環迭代占用 UI 線程,這將導致阻塞,然后返回最終值。

所以你的循環函數實際上是一個同步函數。 假設您這樣做是為了測試目的,模擬async操作的一個好方法是使用Task.Delay

例如:

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

    return 1;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM