how to fetch data from database with async Task in c#?

Farshad Valizade 501 Reputation points
2024-02-02T05:36:17.2766667+00:00

hi every body. I have a code that read data from sql server db and show it in the datagridview. How can I use async await task to do it? DAL code:

public static DataTable GetAll()
{
	using DataTable dt = new();
try
{
	string query = "SELECT  * From Documents";
	using SqlCommand cmd = new(query, Connection.Conn);
	Connection.Open();
	using SqlDataReader rd = cmd.ExecuteReader();
	dt.Load(rd);
}
catch (Exception ex)
{
	Error = ex.Message;
}
finally
{
	Connection.Close();
}
	return dt;
}

BLL:

public static DataTable GetAll() 
{     
	return DocumentDAL.GetAll(); 
}

UI :

 private void btnLoad_Click(object sender, EventArgs e)  
{ 	
	Datagridview1.Datasource = DocumentBLL.GetAll();  
}
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
11,419 questions
0 comments No comments
{count} votes

Accepted answer
  1. Jiale Xue - MSFT 49,831 Reputation points Microsoft External Staff
    2024-02-02T06:00:43.06+00:00

    Hi @Farshad Valizade , Welcome to Microsoft Q&A,

    It should be noted that ADO.NET itself does not support asynchronous operations of SqlConnection or SqlCommand. To achieve asynchronous behavior, you may consider using the "Task.Run" method to offload synchronous operations to a separate thread.

    1. Added Async suffix to GetAllAsync method.
    2. Use "OpenAsync" and "ExecuteReaderAsync" in the DAL for asynchronous operations.
    3. Change the BLL method to return a Task<DataTable> and wait for the DAL method.
    4. Modify UI methods to use await when calling BLL methods.

    Remember, if you use "await" in a UI method, you need to mark it as "async". Also, be aware of potential issues with UI thread synchronization when updating the UI from an asynchronous operation.

    Dal:

    public static async Task<DataTable> GetAllAsync()
    {
        using DataTable dt = new DataTable();
        try
        {
            string query = "SELECT  * From Documents";
            using SqlCommand cmd = new SqlCommand(query, Connection.Conn);
            await Connection.OpenAsync(); // Use OpenAsync for asynchronous opening
            using SqlDataReader rd = await cmd.ExecuteReaderAsync();
            await Task.Run(() => dt.Load(rd)); // Offload synchronous operation to a separate thread
        }
        catch (Exception ex)
        {
            Error = ex.Message;
        }
        finally
        {
            Connection.Close();
        }
        return dt;
    }
    

    BLL:

    public static async Task<DataTable> GetAllAsync()
    {
        return await DocumentDAL.GetAllAsync();
    }
    

    UI:

    private async void btnLoad_Click(object sender, EventArgs e)
    {
        Datagridview1.DataSource = await DocumentBLL.GetAllAsync();
    }
    

    Best Regards,

    Jiale


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment". 

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    2 people found this answer helpful.
    0 comments No comments

1 additional answer

Sort by: Most helpful
  1. Karen Payne MVP 35,566 Reputation points
    2024-02-03T10:00:05.5766667+00:00

    Although you have a solution, take a look at using Dapper.

    • Dapper opens and closes connection for you
    • No need for a command object, Dapper handles this.
    • See one of my Dapper articles Using Dapper - C# Part 1

    Back end

    internal class DataOperations
    {
    	private static IDbConnection db = new SqlConnection("TODO");
        public static async Task<DataTable> GetAll()
        {
            DataTable table = new();
            table.Load(await db.ExecuteReaderAsync("SELECT * FROM dbo.Documents"));
            return table;
        }
    }
    

    Form code

    private async void GetAllButton_Click(object sender, EventArgs e)
    {
        dataGridView1.DataSource = await DataOperations.GetAll();
    }
    
    1 person found this answer helpful.
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.