I have a WPF app that is just a GUI for selecting records from a database based on some criteria. It uses EF Core 5 LINQ syntax but it's, basically, a SELECT with a WHERE clause, under the hood, with a subsequent processing of the returned records.
Currently my setup is the following:
Two projects - WPF and a Console App. The WPF is everything frontend, while the console is the database access.
The WPF window has textboxes and a button. The textboxes are used as the filters for the LINQ .Where()
while the button has an ICommand
bound to it. The command calls a method from the console app that takes the textboxes contents as arguments, selects records from the database and processes the results before returning them to the WPF to be displayed.
I want to delegate the work to other threads/async as best as I can. I'm thinking using async for the database access and multithreading for the processing. However I am not that proficient with async, so I get the problem of "If I make the database access methods async they return a task and I don't know how to tell the ThreadPool to execute that task on another thread, not the UI one."
This is my pseudocode:
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;
}
So, as it is shown, this will run on the UI thread. I want to make it so that the "GetUsers" method would get the list async and EF Core 5 has a .ToListAsync()
method but that requires I make the method async and make it return a Task
and I am not sure how to wait on the result on that task, without blocking AND tell the application to Task.Factory.StartNew(() => ConsoleApp.GetDaData)
at the same time.
Any help is appreciated!
I don't know if this is what you want, but I'll tell you
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;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.