[英]How to call async/await Winforms
我想知道我是否可以讓我的系統響應,或者它向用戶顯示它在短時間內加載一些數據並在程序加載另一個Form
時顯示我的WaitForm
。 因為每當顯示另一個Form
時,我的系統都會暫停一小段時間。
例如:我在這里有我的FrmLogin
並且當用戶輸入他的Username
和Password
時,我希望它在加載另一個WaitForm
時顯示我的 WaitForm,但是當我使用async/await
程序停止時,
這是代碼:
private async void btnLogin_Click(object sender, EventArgs e)
{
await Task.Run(() =>
{
string conn = ConfigurationManager.ConnectionStrings["SystemDatabase"].ConnectionString;
SqlConnection sqlconn = new SqlConnection(conn);
sqlconn.Open();
string query = "Select * from UserAccount where Username = @Username and Password = @Password";
SqlCommand mycommand = new SqlCommand(query, sqlconn);
mycommand.Parameters.AddWithValue("@Username", txtUsername.Text);
mycommand.Parameters.AddWithValue("@Password", txtPassword.Text);
SqlDataReader sdr = mycommand.ExecuteReader();
if (sdr.Read() == true)
{
if (sdr["Designation"].ToString() == "Cashier")
{
FrmWait waitfrm = new FrmWait();
waitfrm.Show();
FrmPOS frm = new FrmPOS();
frm.Show();
frm.lblCashierName.Text = sdr["FullName"].ToString();
waitfrm.Close();
}
else if (sdr["Designation"].ToString() == "Admin")
{
FrmWait waitfrm = new FrmWait();
waitfrm.Show();
Form1 frm = new Form1();
frm.Show();
frm.lblFullname.Text = sdr["FullName"].ToString();
frm.lblPosition.Text = sdr["Designation"].ToString();
byte[] imgBytes = Convert.FromBase64String(sdr["IDPicture"].ToString());
using (MemoryStream ms = new MemoryStream(imgBytes))
{
frm.pbuser.Image = Image.FromStream(ms);
}
FrmStockIn fsi = new FrmStockIn();
fsi.txtStockinby.Text = sdr["FullName"].ToString();
waitfrm.Close();
}
}
else
{
MessageBox.Show("User not Exist!", "My POS", MessageBoxButtons.RetryCancel, MessageBoxIcon.Warning);
}
});
}
任何解決方案或建議將不勝感激。 謝謝你。
像克勞斯說的那樣,刪除你的await Task.Run
並等待運行閱讀器。
但看起來你正在圍繞你的new Form1
/ new FrmPOS
調用包裝一個等待表單 - 如果這些構造函數執行任何需要很長時間或阻塞的繁重 IO 你最好將該代碼移動到表單加載事件(所以至少可以將其設為異步)或單獨的異步方法,以便可以等待它並且不會阻塞 UI 線程/使您的等待表單 go “無響應”
我也會考慮讓那些 forms 負責顯示等待表格,如果他們知道這需要很長時間,而不是這個表格
順便說一句,如果你使用 Dapper,你的生活會變得簡單得多:
//create a class to represent the user; Dapper will query the database and populate this class with information automatically
public class PosUser{
public string FullName{get;set;}
public string Designation{get;set;}
public string IDPicture{get;set;}
}
private async void btnLogin_Click(object sender, EventArgs e)
{
string conn = ConfigurationManager.ConnectionStrings["SystemDatabase"].ConnectionString;
PosUser r;
using(sqlconn = new SqlConnection(conn)){
var query = "Select designation, fullname from UserAccount where Username = @Username and Password = @Password";
var r = await conn.QuerySingleOrDefaultAsync<PosUser>(
query,
new {
Username = txtUsername.Text,
Password = txtPassword.Text.GetHashcode() //at least make some effort to obscure passwords in the db!
}
);
}
if(r == default){
MessageBox.Show("User not Exist!", "My POS", MessageBoxButtons.RetryCancel, MessageBoxIcon.Warning);
return;
}
FrmWait waitfrm = new FrmWait();
waitfrm.Show();
if(r.Designation == "Cashier")
{
FrmPOS frm = new FrmPOS(); //if this does heavy io, move the io to a method you can call async
await frm.DoIoInHereAsync(); //like this, or in an async form load
frm.lblCashierName.Text = r.FullName;
frm.Show();
}
else if (r.Designation == "Admin")
{
Form1 frm = new Form1(); //do not do io in here
await frm.DoIoInHereAsync();
frm.lblFullname.Text = r.FullName;
frm.lblPosition.Text = r.Designation;
byte[] imgBytes = Convert.FromBase64String(r.IDPicture);
using (MemoryStream ms = new MemoryStream(imgBytes))
{
frm.pbuser.Image = Image.FromStream(ms);
}
FrmStockIn fsi = new FrmStockIn(); //do not do io in here
await fsi.DoIoInHereAsync();
fsi.txtStockinby.Text = r.FullName;
}
waitfrm.Close();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.