簡體   English   中英

異步方法不是等待

[英]The async method is not await

在這個線程中,我可以解決我的問題,使用事件在構造函數中等待異步方法。 在這種情況下,事件使用不帶參數的委托。

但是現在我需要等待視圖模型完成以等待異步方法可以繼續。

我的主視圖模型中有此代碼:

public void printMethod()
{
    SecondViewModel mySeocViewModel = new SecondViewModel(myParameter);
    SecondView mySecondView = new SecondView();
    mySecondView.DataContext = mySeocViewModel;

    //I have to wait until it finished to can print the user control
    //The problem is that this point is reached before mySecondViewModel finish.
}

我的第二個視圖模型中的代碼:

public docFacturasViewModel(MyType parameter)
{
    this.GetDataFromDatabaseEvent += OnGetDataFromDatabase;

    GetDataFromDatabaseEvent(parameter);
}


public delegate void GetDataFromDatabaseEventHandler(MyType parameter);
public event GetDataFromDatabaseEventHandler GetDataFromDataBaseEvent;

private async void OnBuscarDatos(MyType paramter)
{
    await getDataFromDatabaseAsync(parameter);

    //Fill the data of the properties of the view model with the data from database
}


private async Task getDataFromDatabaseAsync(MyType parameter)
{
    _myResult = (await getdataAsync(parameter)).FirstOrDefault();
}

如果我調試代碼,它會以這種方式運行:

  • 它到達主視圖模型中的行以創建第二個視圖模型。
  • 在第二個視圖模型中,它到達方法 OnGetDataFromDatabase 中的第一行,即等待。
  • 主視圖模型繼續執行代碼,因此它不會等待來自數據庫的結果。
  • 一段時間后,在第二個視圖模型中,方法 OnGetDataFromDatabase 完成並繼續等待后的下一行代碼。

我不明白為什么在第二個視圖模型中代碼不等到從數據庫中獲取數據,因為我使用的是 await 關鍵字並且所有代碼與我鏈接的帖子的情況相同開始。

謝謝。

編輯:

如果我使用第二個視圖模型的構造函數:

Task.Run(() => buscarDatosAsync(paramFacturaParaImprimir)).Wait();

然后主視圖模型等待第二個視圖模型完成從數據庫中獲取數據。

但是當我在第一種情況下嘗試這種方法時,在我鏈接並在另一篇文章中詢問的情況下,該方法沒有等待,所以我不明白為什么在一種情況下我必須使用委托,而在其他情況我可以使用任務並等待它完成。

async void方法到達await ,控制權返回給調用者。 顯然,當您需要操作的結果來繼續處理時,這不是最好的主意。 除此之外,我不希望構造函數具有創建即發即忘任務的副作用。

如果您需要數據的結果作為對象構造的一部分,我建議您采用工廠方法:

private SecondViewModel()
{
}

public static async Task<SecondViewModel> CreateAsync(MyType parameter)
{
    var result = new SecondViewModel();

    result.SomeData = await getDataFromDatabaseAsync(parameter);

    return result;
}

你會像這樣使用它:

public async Task printMethod()
{
    SecondViewModel mySeocViewModel = await SecondViewModel.CreateAsync(myParameter);
    SecondView mySecondView = new SecondView();
    mySecondView.DataContext = mySeocViewModel;
}

假設您正在編寫一些基於 XAML 的代碼,那么這里存在設計問題。

不要混合視圖模型創建和數據加載。 通常你同步創建視圖模型和視圖,並以異步方式加載/發布數據。 所以,不要在視圖模型構造函數中等待任何東西。

視圖模型和視圖必須在沒有任何數據的情況下正常運行(當數據屬性為null或空集合時)。 如果您不想在加載數據之前訪問某些命令,只需禁用這些命令(從CanExecute返回false )。

暫無
暫無

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

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