简体   繁体   English

如何调用 async/await Winforms

[英]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 .我想知道我是否可以让我的系统响应,或者它向用户显示它在短时间内加载一些数据并在程序加载另一个Form时显示我的WaitForm Because my system pause for a short time whenever a show another Form .因为每当显示另一个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,例如:我在这里有我的FrmLogin并且当用户输入他的UsernamePassword时,我希望它在加载另一个WaitForm时显示我的 WaitForm,但是当我使用async/await程序停止时,

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..像克劳斯说的那样,删除你的await Task.Run并等待运行阅读器。

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"但看起来你正在围绕你的new Form1 / new FrmPOS调用包装一个等待表单 - 如果这些构造函数执行任何需要很长时间或阻塞的繁重 IO 你最好将该代码移动到表单加载事件(所以至少可以将其设为异步)或单独的异步方法,以便可以等待它并且不会阻塞 UI 线程/使您的等待表单 go “无响应”

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我也会考虑让那些 forms 负责显示等待表格,如果他们知道这需要很长时间,而不是这个表格

Your life would become much simpler if you use Dapper, by the way:顺便说一句,如果你使用 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