First of all, I want to mention that I am kinda new to WPF, I just start learning it a few months ago and I am using code behind atm, going to MVVM later... So, Im trying to create a simple program for my discord bot but I want to keep it responsive whenever a database action is going on, meaning my program cannot block while i am -for example- logging into my program. I have a way to archive this but it feels like i am doing something wrong or using Tasking wrong.
I use await Task.Run(() => { code here }) but then inside this task I also need to use the Dispatcher every time I want to update a control and there is where I wonder if i do this all the correct way, is it normal to use the dispatcher inside a Task.Run every time you need to update controls or am I overusing this / doing it wrong?
Currently it works as intented, but I am worried I am overdoing something or going into the wrong direction because for me it seems silly to use the dispatcher every time for updating a control but maybe this is just the way it has to be, i am still new to WPF, this is also my first program i ever did in WPF
Sorry if my english is not so good, i try my best to explain this
I have a sort of solution but the use of Dispatcher inside Tasking seems to me not the correct way, this is the first time im doing this in WPF, I googled around a lot but see people using background workers or threading instead but this still seems to block my UI
// This button I use to -for this example- login in my program
// I load a ContentPresenter over my program showing its 'loading'
// Then I try login
private async void BtnLogin_Click(object sender, RoutedEventArgs e)
{
cpLoader.Visibility = Visibility.Visible;
await TryLoginAsync();
}
// Then here i do the login with tasking
// But here i also need to use dispatcher when updating controls
// So I wonder if this is done correctly
private async Task TryLoginAsync()
{
var username = txtUsername.Text.Trim();
var password = txtPassword.Password.Trim();
if (!string.IsNullOrWhiteSpace(username) && !string.IsNullOrWhiteSpace(password))
{
await Task.Run(() =>
{
try
{
var programAdmin = _dbAdmins.FindBy(x => x.Username.ToLower() == username.ToLower());
if (programAdmin != null)
{
if (string.Equals(EncryptionManager.Decrypt(BotDBConfiguration.EncryptionKey, programAdmin.Password), password))
{
programAdmin.DateLastLogin = DateTime.Now;
programAdmin.TotalLogins += 1;
_dbAdmins.Update(programAdmin);
Dispatcher.BeginInvoke(new Action(() =>
{
var firstTimeLoginPanel = new UpdatePasswordWindow(programAdmin);
firstTimeLoginPanel.Show();
Close();
}));
}
else
{
Dispatcher.BeginInvoke(new Action(() =>
{
cpLoader.Visibility = Visibility.Collapsed;
AlertManager.ShowAlertMessage("Password error", "The given password is incorrect, please try again...");
}));
}
}
else
{
Dispatcher.BeginInvoke(new Action(() =>
{
cpLoader.Visibility = Visibility.Collapsed;
AlertManager.ShowAlertMessage("Admin not found", "The given username cannot be found in the admin database, please try again...");
}));
}
}
catch (Exception)
{
Dispatcher.BeginInvoke(new Action(() =>
{
cpLoader.Visibility = Visibility.Collapsed;
AlertManager.ShowAlertMessage("Connection error", "Cannot connect to the database, please try again later...");
}));
}
});
}
else
{
cpLoader.Visibility = Visibility.Collapsed;
AlertManager.ShowAlertMessage("Missing information", "Please fill in all the required information...");
}
}