我在C#
中使用登录名和密码进行连接,我想
放置一个按钮以取消与数据库的连接(如果连接过多)
长。
我想知道如何做,并尽可能将其放入线程中。
代码如下:
private void btncon_Click(object sender, EventArgs e)
{
string strLogin = tblogin.Text.Trim();
string pass = tbpwd.Text;
bool success = false;
if (String.IsNullOrWhiteSpace(strLogin) || String.IsNullOrWhiteSpace(pass))
{
MessageBox.Show("Veuillez remplir tous les champs SVP ");
}
else if(String.IsNullOrEmpty(strLogin) || String.IsNullOrEmpty(pass)){
MessageBox.Show("Veuillez remplir tous les champs SVP ");
}
else
{
model.Connexion cm = new model.Connexion();
pass = Snippets.SHA1Util.SHA1HashStringForUTF8String(pass).ToString();
string[] user = cm.login(strLogin, pass);
if(user[0] != null)
{
Int32.TryParse(user[0], out iduser);
Int32.TryParse(user[1], out idGrp);
Int32.TryParse(user[2], out idbtq);
nom = user[3];
if (idGrp != 3)
success = true;
else
{
MessageBox.Show("Accès Non autorisé , Veuillez contacter l'administrateur");
success = false;
}
}
else
{
MessageBox.Show("Email ou mot de passe incorrect.");
success = false;
}
}
if (success)
{
main Principale = new main();
Principale.Show();
Hide();`
}
}
答案 0 :(得分:1)
问题在于,当用户单击Cancel
按钮时,无法在执行过程中优雅地取消cm.login()
方法。您可以使用Thread.Abort()
强制终止登录,但这是不安全的,强烈建议不要这样做,因为正确进行登录将需要在另一个AppDomain
中执行代码,并且会使代码变得非常复杂。
幸运的是,如果满足以下条件,您仍然可以实现Cancel
按钮:
cm.login()
是安全的cm.login()
按钮之后,在后台(在另一个线程上)使Cancel
保留在后台(没有其他效果)。此代码还假定它是一个Winform
应用程序(但是WPF
应用程序的解决方案非常相似)。它还假定主窗体具有一个隐藏的按钮btnCancel
(Visible
= false
),并且其Click
事件处理程序设置为btnCancel_Click
方法。 / p>
TaskCompletionSource<Object> CancelLoginTcs = new TaskCompletionSource<Object>();
// Make button click handler method async
private async void btncon_Click(object sender, EventArgs e)
{
try
{
// Make Cancel button visible, so that user can click on it
btnCancel.Visible = true;
// Prepare everything needed to start login
//var strLogin = ...;
//var pass = ...;
//model.Connexion cm = new model.Connexion();
// ...
// Start login on another thread
var loginTask = Task<string[]>.Run(() => cm.login(strLogin, pass));
// Create task that is used to wake-up main thread, when user clicks
// on the Cancel button before login finishes.
CancelLoginTcs = new TaskCompletionSource<Object>();
// Wait for login task or cancel task to complete, whichever finishes first
await Task.WhenAny(loginTask, CancelLoginTcs.Task);
if (CancelLoginTcs.Task.IsCanceled)
{
// User clicked on the Cancel button.
// Login method will be running in the background, until it
// finishes. This assumes that it is safe to do so.
// Here you should do neccessary clean-up, inform user, etc.
// ...
}
else
{
// Login finished and user did NOT click on the Cancel button.
try
{
// Simply read result of login. If an Exception occured during login,
// it will be rethrow now, so you should handle it appropriatelly
var user = loginTask.Result;
// Here program continues in a usual way
// ...
}
catch(Exception E)
{
// Handle login exception
// ...
}
}
}
finally
{
// Hide Cancel button again
btnCancel.Visible = false;
CancelLoginTcs = null;
}
}
private void btnCancel_Click(object sender, EventArgs e)
{
// Set cancel task to cancelled state.
// This will wake-up main thread and let it continue
CancelLoginTcs.SetCanceled();
}