MSDN Documentation

Asynchronous Operations in ADO.NET

ADO.NET provides robust support for asynchronous operations, allowing your applications to remain responsive while performing potentially long-running data access tasks. This is crucial for modern applications, especially those with user interfaces, to prevent blocking and provide a smooth user experience.

Why Use Asynchronous Operations?

Key Concepts and Methods

ADO.NET introduces asynchronous equivalents for many of its synchronous methods. These typically follow a pattern of appending Async to the original method name and returning a Task or Task<TResult>.

Some common asynchronous methods include:

Using async and await

The C# async and await keywords are fundamental to working with asynchronous operations in ADO.NET. The await keyword pauses the execution of the asynchronous method until the awaited task completes, without blocking the thread.

Example: Executing a Non-Query Asynchronously

C# Code Example


using System;
using System.Data.SqlClient;
using System.Threading.Tasks;

public class AsyncDataAccess
{
    private string connectionString = "Your_Connection_String_Here";

    public async Task AddProductAsync(string productName, decimal price)
    {
        using (SqlConnection connection = new SqlConnection(connectionString))
        {
            string query = "INSERT INTO Products (Name, Price) VALUES (@Name, @Price)";
            SqlCommand command = new SqlCommand(query, connection);
            command.Parameters.AddWithValue("@Name", productName);
            command.Parameters.AddWithValue("@Price", price);

            try
            {
                await connection.OpenAsync();
                int rowsAffected = await command.ExecuteNonQueryAsync();
                Console.WriteLine($"{rowsAffected} row(s) affected.");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error adding product: {ex.Message}");
            }
        }
    }

    // Example of calling the async method
    public static async Task Main(string[] args)
    {
        AsyncDataAccess dataAccess = new AsyncDataAccess();
        await dataAccess.AddProductAsync("New Gadget", 99.99m);
    }
}
                    

Example: Reading Data Asynchronously

C# Code Example


using System;
using System.Data.SqlClient;
using System.Threading.Tasks;
using System.Collections.Generic;

public class AsyncDataReaderExample
{
    private string connectionString = "Your_Connection_String_Here";

    public async Task<List<string>> GetProductNamesAsync()
    {
        var productNames = new List<string>();
        using (SqlConnection connection = new SqlConnection(connectionString))
        {
            string query = "SELECT Name FROM Products ORDER BY Name";
            SqlCommand command = new SqlCommand(query, connection);

            try
            {
                await connection.OpenAsync();
                using (SqlDataReader reader = await command.ExecuteReaderAsync())
                {
                    while (await reader.ReadAsync())
                    {
                        productNames.Add(reader.GetString(0)); // GetString(0) assumes Name is the first column and is a string
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error retrieving product names: {ex.Message}");
            }
        }
        return productNames;
    }

    // Example of calling the async method
    public static async Task Main(string[] args)
    {
        AsyncDataReaderExample readerExample = new AsyncDataReaderExample();
        List<string> names = await readerExample.GetProductNamesAsync();
        Console.WriteLine("Product Names:");
        foreach (var name in names)
        {
            Console.WriteLine($"- {name}");
        }
    }
}
                    

Considerations

By embracing asynchronous programming patterns with ADO.NET, you can build more robust, responsive, and scalable data-driven applications.