簡體   English   中英

如何調用 async/await Winforms

[英]How to call async/await Winforms

我想知道我是否可以讓我的系統響應,或者它向用戶顯示它在短時間內加載一些數據並在程序加載另一個Form時顯示我的WaitForm 因為每當顯示另一個Form時,我的系統都會暫停一小段時間。

例如:我在這里有我的FrmLogin並且當用戶輸入他的UsernamePassword時,我希望它在加載另一個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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM