簡體   English   中英

WPF MVVM ViewModel 多線程和從后端請求數據時的異步

[英]WPF MVVM ViewModel multithreading and async when requesting data from the backend

我有一個 WPF 應用程序,它只是一個 GUI,用於根據某些條件從數據庫中選擇記錄。 它使用 EF Core 5 LINQ 語法,但它基本上是一個帶有 WHERE 子句的 SELECT,在后台對返回的記錄進行后續處理。

目前我的設置如下:

兩個項目 - WPF 和一個控制台應用程序。 WPF 是前端,而控制台是數據庫訪問。
WPF window 有文本框和一個按鈕。 文本框用作 LINQ .Where()的過濾器,而按鈕綁定了一個ICommand 該命令從控制台應用程序調用一個方法,該方法將文本框內容作為 arguments,從數據庫中選擇記錄並處理結果,然后將它們返回到 WPF 進行顯示。

我想盡我所能將工作委托給其他線程/異步。 我正在考慮使用異步進行數據庫訪問和多線程處理。 但是我對異步並不那么精通,所以我遇到了這樣的問題:“如果我讓數據庫訪問方法異步,它們會返回一個任務,我不知道如何告訴線程池在另一個線程上執行該任務,而不是在 UI 上一。”

這是我的偽代碼:

public class ConsoleApp
{
    public List<TUser> GetDaData(string userName, string department)
    {
        var users = GetUsers(userName, department);
        return ProcessUsers(users);
    }

    private List<TUser> ProcessUsers(List<TUser> users)
    {
        // do work
    }

    private List<TUser> GetUsers(string userName, string department)
    {
        dbContext.TUsers.Where(user =>
            (user.Name == userName || userName == null)
            && (user.Department == department || department == null)).ToList();
    }
}


class WpfStuff
{
    public UserName, Department; // pseudo properties with backing fields, databound to the TextBoxes content properties.
    public List<TUser> Users; // pseudo property with backing field, databound to a DataGrid's "ItemSource" property.

    public WpfStuff
    {
        // this is the command databound to the button.
        GetUsersCommand = new RelayCommand(OnGetUsers, CanGetUsers);
    }

    void OnGetUsers()
    {
        Users = ConsoleApp.GetDaData(UserName, Department);
    }

    bool CanGetUsers() => true;
}

因此,如圖所示,這將在 UI 線程上運行。 我想做到這一點,以便“GetUsers”方法獲得異步列表,而 EF Core 5 有一個.ToListAsync()方法,但這需要我使方法異步並使其返回一個Task ,我不確定如何等待在該任務的結果上,不阻塞並同時告訴應用程序Task.Factory.StartNew(() => ConsoleApp.GetDaData)

任何幫助表示贊賞!

我不知道這是不是你想要的,但我會告訴你

public class ConsoleApp
{
    // ----- 
    // add 'async'
    // -----
    public async Task<List<TUser>> GetDaData(string userName, string department)
    {
        var users = GetUsers(userName, department);
        return ProcessUsers(users);
    }

    private List<TUser> ProcessUsers(List<TUser> users)
    {
        // do work
    }

    private List<TUser> GetUsers(string userName, string department)
    {
        dbContext.TUsers.Where(user =>
            (user.Name == userName || userName == null)
            && (user.Department == department || department == null)).ToList();
    }
}


class WpfStuff
{
    public UserName, Department; // pseudo properties with backing fields, databound to the TextBoxes content properties.
    public List<TUser> Users; // pseudo property with backing field, databound to a DataGrid's "ItemSource" property.

    public WpfStuff
    {
        // this is the command databound to the button.
        GetUsersCommand = new RelayCommand(OnGetUsers, CanGetUsers);
    }

    // i'm not sure, this need async....
    void OnGetUsers()
    {
        Users = await Task.Run(ConsoleApp.GetDaData(UserName, Department));
    }

    bool CanGetUsers() => true;
}

暫無
暫無

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

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