这是我的登录方法:
#region LoginMethod
bool login = false;
public async Task GetAccounts()
{
MainWin w = new MainWin();
await Task.Run(() =>
{
this.Dispatcher.Invoke(() =>
{
using (SqlConnection connection = new SqlConnection(PublicVar.ConnectionString))
{
gymEntities2 database = new gymEntities2();
SqlConnection con1 = new SqlConnection(PublicVar.ConnectionString);
PublicVar.TodayTime = String.Format("{0:yyyy/MM/dd}", Convert.ToDateTime(TimeNow.Text));
con1.Open();
SqlCommand Actives = new SqlCommand("Select DISTINCT (LockEndDate) from LockTable Where Username = '" + txt_username.Text + "' and Password = '" + txt_password.Password + "'", con1);
object Active = Actives.ExecuteScalar();
string SystemActive = Convert.ToString(Active);
// SqlCommand Commandcmds = new SqlCommand("update VW_TimeOut set UserActive = 2 where UserEndDate < '" + String.Format("{0:yyyy/MM/dd}", Convert.ToDateTime(TimeNow.Text)) + "'", con1);
// Commandcmds.ExecuteScalar();
SqlCommand Commandcmd = new SqlCommand("SELECT COUNT(*) FROM LockTable Where Username = '" + txt_username.Text + "' and Password = '" + txt_password.Password + "' and LockEndDate between '" + String.Format("{0:yyyy/MM/dd}", Convert.ToDateTime(Lock.Text)) + "' And '" + SystemActive + "'", con1);
int userCount = (int)Commandcmd.ExecuteScalar();
//Find Gym ID -> To Set Public Value Strings
SqlCommand FindGymID = new SqlCommand("Select DISTINCT (LockID) from LockTable Where Username = '" + txt_username.Text + "' and Password = '" + txt_password.Password + "'", con1);
object ObGymID = FindGymID.ExecuteScalar();
if (userCount > 0)
{
try
{
RegistryKey UsernameKey = Registry.CurrentUser.CreateSubKey("SOFTWARE\\GYM");
if (CheakRem.IsChecked == true)
if ((string)UsernameKey.GetValue("UserNameRegister") != "")
{
UsernameKey.SetValue("UserNameRegister", txt_username.Text.Trim());
UsernameKey.SetValue("PasswordRegister", Module.Decode.EncryptTextUsingUTF8(txt_password.Password.Trim()));
}
PublicVar.GymID = Convert.ToString(ObGymID);
login = true;
}
catch
{
w.Username = null;
w.Password = null;
}
}
else
{
ErrorPage pageerror = new ErrorPage();
con1.Close();
w.Username = null;
w.Password = null;
}
con1.Close();
}
});
});
if (login == true)
{
w.Username = txt_username.Text;
w.Password = txt_password.Password;
w.Show();
this.Close();
}
}
#endregion
但是它不起作用-每当我按下按钮时,我的表单就会挂起。
private async void btn_join_Click(object sender, RoutedEventArgs e)
{
await GetAccounts();
}
它不起作用,并且当我按下异步按钮时我的程序被挂起。 我的方法的哪一部分是错误的? 我真正想要的是按下按钮以打开新页面, 但我不希望它延迟打开……有人告诉我使用await方法,但它仍然会延迟打开。
答案 0 :(得分:1)
您通过在任务方法中使用Dispatcher.Invoke()来挂起程序。
Dispatcher.Invoke()导致代码在WPF的UI线程上同步执行,并且在此代码完成之前不会返回。同时,在“异步按钮”中,代码等待任务完成,这就是您的僵局。
您不需要Task.Run with Dispatcher.Invoke。
您应该执行以下操作:
如果您显示更多代码,我会更加精确。
答案 1 :(得分:1)
看看这一行this.Dispatcher.Invoke(() =>
Dispatcher.Invoke
是一个同步调用,它将阻止您的线程运行直到完成。在回调返回之前,控件将不会返回到调用对象,因此会导致GUI不响应。
您可能想使用Dispatcher.BeginInvoke
而不是Dispatcher.Invoke
(example),它是异步操作。或仅在确实需要修改或更新UI内容时才使用Dispatcher.Invoke
。例子
Dispatcher.Invoke(() =>
{
w.Username = null;
w.Password = null;
});
答案 2 :(得分:1)
以上两个答案都是正确的。但是也许修复您的代码会使事情变得更清楚。您应该按照上面的建议和如下所示将UI与任务分开。希望我没有语法错误,因为我只是在没有IDE的情况下对其进行了修改。基本上,我将GetAccounts更改为仅处理数据库,而让PopulateMethodAsync处理UI。这意味着GetAccounts将在后台运行,完成后会将结果提供给UI部分(PopulateMethodAsync)。
#region LoginMethod
bool login = false;
public async Task PopulateMethodAsync()
{
var isLoginSuccess = await GetAccounts(txt_username.Text.Trim(), txt_password.password.Text.Trim(), Lock.Text.Trim(), TimeNow.Text.Trim());
MainWin w = new MainWin();
if (login == true)
{
w.Username = txt_username.Text;
w.Password = txt_password.Password;
w.Show();
this.Close();
}
else
{
w.Username = null;
w.Password = null;
}
}
public async Task<bool> GetAccounts(string txt_username, string txt_password, string Lock, string TimeNow)
{
await Task.Run(() =>
{
using (SqlConnection connection = new SqlConnection(PublicVar.ConnectionString))
{
gymEntities2 database = new gymEntities2();
SqlConnection con1 = new SqlConnection(PublicVar.ConnectionString);
PublicVar.TodayTime = String.Format("{0:yyyy/MM/dd}", Convert.ToDateTime(TimeNow));
con1.Open();
SqlCommand Actives = new SqlCommand("Select DISTINCT (LockEndDate) from LockTable Where Username = '" + txt_username + "' and Password = '" + txt_password + "'", con1);
object Active = Actives.ExecuteScalar();
string SystemActive = Convert.ToString(Active);
// SqlCommand Commandcmds = new SqlCommand("update VW_TimeOut set UserActive = 2 where UserEndDate < '" + String.Format("{0:yyyy/MM/dd}", Convert.ToDateTime(TimeNow.Text)) + "'", con1);
// Commandcmds.ExecuteScalar();
SqlCommand Commandcmd = new SqlCommand("SELECT COUNT(*) FROM LockTable Where Username = '" + txt_username + "' and Password = '" + txt_password + "' and LockEndDate between '" + String.Format("{0:yyyy/MM/dd}", Convert.ToDateTime(Lock)) + "' And '" + SystemActive + "'", con1);
int userCount = (int)Commandcmd.ExecuteScalar();
//Find Gym ID -> To Set Public Value Strings
SqlCommand FindGymID = new SqlCommand("Select DISTINCT (LockID) from LockTable Where Username = '" + txt_username + "' and Password = '" + txt_password + "'", con1);
object ObGymID = FindGymID.ExecuteScalar();
if (userCount > 0)
{
try
{
RegistryKey UsernameKey = Registry.CurrentUser.CreateSubKey("SOFTWARE\\GYM");
if (CheakRem.IsChecked == true)
if ((string)UsernameKey.GetValue("UserNameRegister") != "")
{
UsernameKey.SetValue("UserNameRegister", txt_username);
UsernameKey.SetValue("PasswordRegister", Module.Decode.EncryptTextUsingUTF8(txt_password));
}
PublicVar.GymID = Convert.ToString(ObGymID);
con1.Close();
return true;
}
catch
{
}
}
con1.Close();
}
});
return false;
}
#endregion
private async void btn_join_Click(object sender, RoutedEventArgs e)
{
await PopulateMethodAsync();
}
希望这能回答您的问题