Search code examples
c#async-awaitdesktop-application

task async datatable on showdialog form problem


I want to create the simple async popup windows application, and the windows form is showdialog at end. But when I run the program , the program auto exit without error Can you help me solve , here is my code

    private static string pridbUser = "user";
    private static string pridbPwd = "abc123";
    public void run()
    {
        string cnnStr = @"Data Source=localhost;Initial Catalog=sampledb;User ID=" + pridbUser + ";Password=" + pridbPwd + ";MultipleActiveResultSets=true";
        string sql = "SELECT * FROM [TABLE1]";
        using (SqlConnection sqlcnn = new SqlConnection(cnnStr))
        {
            sqlcnn.Open();
            var tskJob = CreateTableAsync(sql, sqlcnn);                
            using (frmUI ui = new frmUI())
            {
                Task.WhenAll(tskJob);
                ui.BindControl(tskJob.Result.DefaultView);
                ui.ShowDialog();
            }

        }        
    }
    private async Task<DataTable> CreateTableAsync(string sql, SqlConnection dbCnn)
    {

        using (SqlCommand _c = new SqlCommand(sql, dbCnn))
        {
            DataTable dt = new DataTable();
            dt.Load(await _c.ExecuteReaderAsync());
            return dt;
        }

    }

Revise, hi , thanks for your comment, then I rewrite the async job, but the result is not my want, the code below :

private static string pridbUser = "user";
private static string pridbPwd = "abc123";
public void run()
{
    string cnnStr = @"Data Source=localhost;Initial Catalog=sampledb;User ID=" + pridbUser + ";Password=" + pridbPwd + ";MultipleActiveResultSets=true";
    string sql = "SELECT * FROM [TABLE1]";
    using (SqlConnection sqlcnn = new SqlConnection(cnnStr))
    {
        sqlcnn.Open();
        Console.WriteLine("Create Table with Asyn mode");
        var tskJob = CreateTableAsync(sql, sqlcnn);                
        using (frmUI ui = new frmUI())
        {
            Console.WriteLine("Create Form Complete");
            Task.WhenAll(tskJob);
            ui.BindControl(tskJob.Result.DefaultView);
            ui.ShowDialog();
        }

    }        
}
private async Task<DataTable> CreateTableAsync(string sql, SqlConnection dbCnn)
{
    Console.WriteLine("Start to Create Table")
    using (SqlCommand _c = new SqlCommand(sql, dbCnn))
    {
        DataTable dt = new DataTable();
        dt.Load(await _c.ExecuteReaderAsync());
        Console.WriteLine("Delay 5 second")
        Thread.Sleep(5000); // delay 5 seconds
        Console.WriteLine("End Delay")
        return dt;
    }

}

The running result is :

Create Table with Asyn mode
Start to Create Table
Delay 5 second
End Delay and Return
Create the Form Complete
Bind Control

But my expect result should be

Create Table with Asyn mode
Start to Create Table
Create the Form Complete
Delay 5 second <-- as it should not wait 5 second and then run form in async process
End Delay and Return
Bind Control

Can you have any good advise


Solution

  • You need to await the call to Task.WhenAll() (or call Wait(), if you can't, as shown in the Examples section of Task.WhenAll Method doco.

    Also in your CreateTableAsync you should await the Task.Delay call.

    Here are some suggestions:

    var tskJob = CreateTableAsync(sql, sqlcnn);   
    tskJob.Wait() // Normally, you should use await if possible             
                using (frmUI ui = new frmUI())
                {
                    // not needed Task.WhenAll(tskJob);
                    ui.BindControl(
    
    (...)
    
    // Change Thread.Sleep(5000); // delay 5 seconds
    //to
    await Task.Delay(TimeSpan.FromSeconds(5));