繁体   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