简体   繁体   中英

How to call async/await Winforms

I wonder if I can make my system responsive or it shows the user that its loading some data for a short time and show my WaitForm while the program loads another Form . Because my system pause for a short time whenever a show another Form .

For example: I have here my FrmLogin and when the user inputs his Username and Password , I want it to shows my WaitForm while loading the other forms, but when I use async/await the programs stops,

Here is the code:

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);
        }
    });
}

Any solution or suggestion would be appreciated. Thank you.

Do like Klaus said, remove your await Task.Run and await running the reader instead..

But also it looks like you're wrapping a waiting form around your new Form1 / new FrmPOS calls - if those constructors do any heavy IO that is taking long or jamming up you would be better off moving that code to a form load event (so at least it can be made async) or a separate method that is async, so that it can be awaited and doesn't jam the UI thread/make your wait form go "not responding"

I would also look at making those forms responsible for showing the wait form if they know it's gonna take long, not this form

Your life would become much simpler if you use Dapper, by the way:

//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();

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM