C# 从后端请求数据时WPF MVVM ViewModel多线程和异步

C# 从后端请求数据时WPF MVVM ViewModel多线程和异步,c#,wpf,multithreading,asynchronous,async-await,C#,Wpf,Multithreading,Asynchronous,Async Await,我有一个WPF应用程序,它只是一个GUI,用于根据一些标准从数据库中选择记录。它使用EF Core 5 LINQ语法,但基本上,它是一个带有WHERE子句的SELECT,隐藏在引擎盖下,对返回的记录进行后续处理 目前我的设置如下: 两个项目-WPF和一个控制台应用程序。WPF是前端,而控制台是数据库访问。 WPF窗口有文本框和按钮。文本框用作LINQ.Where的过滤器,而按钮绑定了ICommand。该命令从控制台应用程序调用一个方法,该方法将文本框内容作为参数,从数据库中选择记录并处理结果,然

我有一个WPF应用程序,它只是一个GUI,用于根据一些标准从数据库中选择记录。它使用EF Core 5 LINQ语法,但基本上,它是一个带有WHERE子句的SELECT,隐藏在引擎盖下,对返回的记录进行后续处理

目前我的设置如下:

两个项目-WPF和一个控制台应用程序。WPF是前端,而控制台是数据库访问。 WPF窗口有文本框和按钮。文本框用作LINQ.Where的过滤器,而按钮绑定了ICommand。该命令从控制台应用程序调用一个方法,该方法将文本框内容作为参数,从数据库中选择记录并处理结果,然后将其返回到要显示的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有一个.toListSync方法,但这需要我使该方法异步并使其返回一个任务,我不确定如何等待该任务的结果,而不阻塞并同时将应用程序告知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;
}