Multithreadin backgroundworker async&等待登录到SQL C#WPF [英] Multithreadin backgroundworker async & await login to SQL C# WPF
问题描述
大家好,
我有一个带有用户数据库的C#WPF应用程序。我拥有它,所以具有正确信息的用户可以登录,并且如果他们是管理员或客户,它将把他们带到他们适当的菜单。现在我希望在程序检查数据库中的用户信息时加载.gif文件。我在想我应该使用多线程,但在调查它时可能我应该使用backgroundworker或async并等待。我不确定应该使用哪一个。我尝试了我的代码与后台工作者我将我的登录代码移动到'Dowork'方法但是当我运行程序时它说我的控件不在正确的线程中。
任何让这个GIF上班的方法都会受到赞赏。这就是我所拥有的。
public partial class LoginScreen:Window
{
private 用户loginUser = 新用户( );
BackgroundWorker backgroundWorker = null ;
public LoginScreen()
{
InitializeComponent();
txtUsername.Text = 用户名;
txtPassword.Password = 密码;
InstantiateBackgroundWorker();
}
private void BtnLoginUser_Click( object sender,RoutedEventArgs e)
{
string username = txtUsername.Text;
string password = txtPassword.Password;
if ( string .IsNullOrEmpty(txtUsername.Text))
{
// 验证并输入用户名。
MessageBox.Show(< span class =code-string> 输入您的用户名。, < span class =code-string> Empty,MessageBoxButton.OK,MessageBoxImage.Information);
txtUsername.Focus();
return ;
}
其他 如果( string .IsNullOrEmpty(txtPassword.Password))
{
MessageBox.Show( 输入您的密码。, 空,MessageBoxButton.OK,MessageBoxImage.Information );
txtPassword.Focus();
return ;
}
其他
{
// < span class =code-comment>开始加载Gif
LoadSpinner.Visibility = Visibility.Visible;
// 禁用登录和注册按钮。
BtnLoginUser。 IsEnabled = false ;
BtnCreateUser.IsEnabled = false ;
// 启动后台工作程序。
backgroundWorker.RunWorkerAsync ();
// 尝试
// {
// loginUser = SQLuserAccess.UserLogin(txtUsername.Text,txtPassword.Password.ToString());
// if(loginUser!= null)
// {
// if(txtUsername.Text == loginUser.Username&& ; txtPassword.Password == loginUser.Password)
// {
// if(logi nUser.IsAdmin == true)
// {
// 窗口showAdminSrc = new AdminWindow(loginUser);
// showAdminSrc.Show();
// < span class =code-comment> Close();
// }
// 否则if(loginUser.IsAdmin == false)
// {
// 窗口nonAdmi n = new CustomerScreen(loginUser);
// nonAdmin.Show();
// 关闭();
// }
// else
// lblInvalidText.Content =管理员不是真或错!;
// }
// else
// {
// lblInvalidText.Visibility = Visibility.Visible;
// }
// }
// else
// lblInvalidText.Visibility = Visibility.Visible;
// }
// catch(Exception ex)
// {
// //lblInvalidText.Visibility = Visibility.Visible;
// MessageBox.Show(ex.Message.ToString());
// }
}
}
private void InstantiateBackgroundWorker()
{
backgroundWorker = new BackgroundWorker();
backgroundWorker.ProgressChanged + = BackgroundWorker_ProgressChanged;
backgroundWorker.DoWork + = BackgroundWorker_DoWork;
backgroundWorker.RunWorkerCompleted + = BackgroundWorker_RunWorkerCompleted;
backgroundWorker.WorkerReportsProgress = true ;
}
private void BackgroundWorker_RunWorkerCompleted( object sender,RunWorkerCompletedEventArgs e)
{
// 停止加载
// 抛出新的NotImplementedException();
LoadSpinner.Visibility = Visibility.Hidden;
}
私有 void BackgroundWorker_DoWork( object sender,DoWorkEventArgs e)
{
// ??开始加载??
// 抛出新的NotImplementedException();
string username = txtUsername.Text;
string password = txtPassword.Password;
try
{
loginUser = SQLuserAccess.UserLogin(username,password);
if (loginUser!= null )
{
if (username == loginUser.Username&& password == loginUser.Password)
{
if (loginUser.IsAdmin)
{
Window WindowAdminMenu = new AdminWindow(loginUser);
WindowAdminMenu.Show();
关闭();
}
else if (loginUser.IsCustomer)
{
Window WindowCustomerMenu = new CustomerScreen(loginUser);
WindowCustomerMenu.Show();
关闭();
}
else
lblInvalidText.Content = 无效的帐户信息;
}
else
lblInvalidText.Visibility = Visibility.Visible;
}
else
lblInvalidText.Visibility = Visibility.Visible;
}
catch (Exception ex){MessageBox.Show(ex.Message.ToString()); }
}
private void BackgroundWorker_ProgressChanged( object sender,ProgressChangedEventArgs e)
{
LblWatch.Content = e.UserState.ToString();
}
私有 void LoadSpinner_MediaEnded( object sender,RoutedEventArgs e)
{
LoadSpinner.Position = new TimeSpan( 0 , 0 , 1 );
LoadSpinner.Play();
}
我的尝试:
后台工作者方法进度dowork n完成说来自另一个线程
你是在正确的轨道上,你可以使用Backgroundworker来达到这个目的在使用多线程时,只需记住一些事情就是,我们无法直接从另一个线程访问UI元素。
由于在Backgroundworker中执行的整个代码在另一个线程中,我们无法访问或修改它们因此,当您在Backgroundworker中编写逻辑时,我们不必使用UI元素,或者如果需要,您可以在之前访问它们,例如在您的情况下
Quote:string username = txtUsername.Text;
string password = txtPassword.Password;
make username &安培;密码作为全局变量&在引用之前分配值:backgroundWorker.RunWorkerAsync();
或者当使用这样的时候
Quote:lblInvalidText.Content =无效的帐户信息;
您必须让Dispatcher(基本上是您的UI线程)知道您正在更改任何元素,因此您需要在
中编写该代码
Dispatcher.BeginInvoke(DispatcherPriority.Send, new 动作(()= > {
// 您的逻辑
});
有关Dispatcher的更多信息,您可以查看link
Hello all,
I have a C# WPF application with a database of users. I have it so a user with the correct info can login and depending if they are an Admin or a Customer it will take them to their appropriate menu. Now I want to have a loading .gif while the program is checking the database for the users information. I was thinking I should use multi-threading but while looking into it maybe I should use backgroundworker or async and await. I am not sure which one I should use. I tried my code with backgroundworker I moved my login code to the ‘Dowork’ method but when I run the program it says that my controls are not in the correct thread.
Any ways to get this gif to work would be appreciated it here is what I have.
public partial class LoginScreen : Window
{
private User loginUser = new User();
BackgroundWorker backgroundWorker = null;
public LoginScreen()
{
InitializeComponent();
txtUsername.Text = "Username";
txtPassword.Password = "Password";
InstantiateBackgroundWorker();
}
private void BtnLoginUser_Click(object sender, RoutedEventArgs e)
{
string username = txtUsername.Text;
string password = txtPassword.Password;
if (string.IsNullOrEmpty(txtUsername.Text))
{
//verify and enter username.
MessageBox.Show("Enter your username.", "Empty", MessageBoxButton.OK, MessageBoxImage.Information);
txtUsername.Focus();
return;
}
else if (string.IsNullOrEmpty(txtPassword.Password))
{
MessageBox.Show("Enter your password.", "Empty", MessageBoxButton.OK, MessageBoxImage.Information);
txtPassword.Focus();
return;
}
else
{
// Start loading Gif
LoadSpinner.Visibility = Visibility.Visible;
// Disable login and register button.
BtnLoginUser.IsEnabled = false;
BtnCreateUser.IsEnabled = false;
// Start the background worker.
backgroundWorker.RunWorkerAsync();
//try
//{
// loginUser = SQLuserAccess.UserLogin(txtUsername.Text, txtPassword.Password.ToString());
// if (loginUser != null)
// {
// if (txtUsername.Text == loginUser.Username && txtPassword.Password == loginUser.Password)
// {
// if (loginUser.IsAdmin == true)
// {
// Window showAdminSrc = new AdminWindow(loginUser);
// showAdminSrc.Show();
// Close();
// }
// else if (loginUser.IsAdmin == false)
// {
// Window nonAdmin = new CustomerScreen(loginUser);
// nonAdmin.Show();
// Close();
// }
// else
// lblInvalidText.Content = "Admin is not True or False!";
// }
// else
// {
// lblInvalidText.Visibility = Visibility.Visible;
// }
// }
// else
// lblInvalidText.Visibility = Visibility.Visible;
//}
//catch(Exception ex)
//{
// //lblInvalidText.Visibility = Visibility.Visible;
// MessageBox.Show(ex.Message.ToString());
//}
}
}
private void InstantiateBackgroundWorker()
{
backgroundWorker = new BackgroundWorker();
backgroundWorker.ProgressChanged += BackgroundWorker_ProgressChanged;
backgroundWorker.DoWork += BackgroundWorker_DoWork;
backgroundWorker.RunWorkerCompleted += BackgroundWorker_RunWorkerCompleted;
backgroundWorker.WorkerReportsProgress = true;
}
private void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//Stop the loading
//throw new NotImplementedException();
LoadSpinner.Visibility = Visibility.Hidden;
}
private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
// ?? Start the loading ??
//throw new NotImplementedException();
string username = txtUsername.Text;
string password = txtPassword.Password;
try
{
loginUser = SQLuserAccess.UserLogin(username, password);
if (loginUser != null)
{
if (username == loginUser.Username && password == loginUser.Password)
{
if (loginUser.IsAdmin)
{
Window WindowAdminMenu = new AdminWindow(loginUser);
WindowAdminMenu.Show();
Close();
}
else if (loginUser.IsCustomer)
{
Window WindowCustomerMenu = new CustomerScreen(loginUser);
WindowCustomerMenu.Show();
Close();
}
else
lblInvalidText.Content = "Invalid Account Information";
}
else
lblInvalidText.Visibility = Visibility.Visible;
}
else
lblInvalidText.Visibility = Visibility.Visible;
}
catch(Exception ex) { MessageBox.Show(ex.Message.ToString()); }
}
private void BackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
LblWatch.Content = e.UserState.ToString();
}
private void LoadSpinner_MediaEnded(object sender, RoutedEventArgs e)
{
LoadSpinner.Position = new TimeSpan(0, 0, 1);
LoadSpinner.Play();
}
What I have tried:
background worker methods progress dowork n completed says from a different thread
Hi, you are on right track, you could use Backgroundworker for this purpose with ease, just remember some thing while working with multithread is that, we cannot access UI elements directly from another thread.
And as entire code that's executed in Backgroundworker is in another thread we cannot access or modify them, hence when you write your logic in Backgroundworker implement logic such that we do not have to use UI elements or if its needed you can access them before i.e in your case
Quote:string username = txtUsername.Text;
string password = txtPassword.Password;
make username & password as global variable & assign the value beforeQuote:backgroundWorker.RunWorkerAsync();
or else when using such
Quote:lblInvalidText.Content = "Invalid Account Information";
you have to let Dispatcher (basically your UI thread) know that you are changing any of there elements, hence you need to write that code in
Dispatcher.BeginInvoke(DispatcherPriority.Send,new Action(()=>{ //your logic });
For more information on Dispatcher you can check out this link
这篇关于Multithreadin backgroundworker async&等待登录到SQL C#WPF的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!