4. 异步数据访问

    技术2022-07-10  145

    访问数据库可能要花一些时间。这里不应该阻塞用户界面。ADO.NET类通过异步方法和同步方法提供了基于任务的异步编程。下面的代码片段类似于上一个使用SqlDataReader的代码,但它使用了异步的方法调用。连接用SqlConnection.OpenAsync打开,读取器从SqlCommand.ExecuteReaderAsync方法中返回,记录使用SqlDataReader.ReadAsync检索。在所有这些方法中,调用线程没有阻塞,但是可以在得到结果前,执行其他操作:

    public static async Task ReadAsync(string title) { var connection = new SqlConnection(GetConnectionString()); string sql = "SELECT [Id],[Title],[Publisher],[Isbn],[ReleaseDate] "+ "FROM [ProCSharp].[Books] WHERE lower([Title]) LIKE @Title ORDER BY [ReleaseDate]"; var command = new SqlCommand(sql,connection); command.Parameters.Add("@Title",SqlDbType.NVarChar,50); command.Parameters["@Title"].Value = title; await connection.OpenAsync(); //使用异步任务取消 //var source = new CancellationTokenSource(); //source.CancelAfter(1000); //await connection.OpenAsync(source.Token); using (SqlDataReader reader = await command.ExecuteReaderAsync(CommandBehavior.CloseConnection)) { while (await reader.ReadAsync()) { int id = reader.GetInt32(0); string bookTitle = reader.GetString(1); string publisher = reader.GetString(2); string isbn = reader.GetString(3); DateTime? releaseDate = reader.IsDBNull(4) ? (DateTime?)null : reader.GetDateTime(4); Console.WriteLine($"{id,5}. {bookTitle,-20} {publisher,-20} {isbn,-20} {releaseDate:d}"); } } }

    注意:

    异步Main()方法至少需要C#7.1。

    运行结果:

    2045. wxg Wrox Press 123234234 2044. wxg Wrox Press 124567852 2020/4/5

    使用异步方法调用,不仅有利于Windows应用程序,也有利于在服务器端同时进行多个调用。ADO.NET API的异步方法有重载版本来支持CancellationToken,使长时间运行的方法早些停止。

    Processed: 0.042, SQL: 9