我是否应该升级以能够为SqlDataReader使用新的异步方法?

时间:2022-10-06 13:49:54

I'm working on a large project that runs on .NET 4.0. This framework uses ADO.NET for database calls and we're currently adding asynchronous API methods. The SqlCommand class has the APM methods SqlCommand.BeginExecuteReader() and SqlCommand.EndExecuteReader(), but SqlDataReader does not have asynchronous implementations.
When the SqlCommand.ExecuteReader() is finished I want to iterate through the results using SqlDataReader. Microsoft introduces asynchronous methods for SqlDataReader in .NET 4.5, so I can't use those in 4.0.

我正在做一个运行在。net 4.0上的大型项目。这个框架使用ADO。NET用于数据库调用,我们目前正在添加异步API方法。SqlCommand类有APM方法SqlCommand. beginexecutereader()和SqlCommand. endexecutereader(),但是SqlDataReader没有异步实现。当SqlCommand.ExecuteReader()完成时,我希望使用SqlDataReader对结果进行迭代。微软在。net 4.5中引入了SqlDataReader的异步方法,所以我不能在4.0中使用它们。

Question: Should we upgrade to be able to use the asynchronous (TAP) methods of SqlDataReader? If we do, why?

问:我们是否应该升级以能够使用SqlDataReader的异步(TAP)方法?如果我们这样做了,为什么?

I searched the web and * alot for answers, but I only seem to find implementations for this. It doesn't tell me what benefit those new implementations give.

我搜索了web和*,找到了很多答案,但我似乎只找到了实现。它没有告诉我这些新实现带来了什么好处。

.NET 4.0 implementation

Here we use the asynchronous methods of SqlCommand, but we can't use the new asynchronous methods for SqlDataReader, like SqlDataReader.ReadAsync().

这里我们使用SqlCommand的异步方法,但是不能使用SqlDataReader的新异步方法,比如SqlDataReader. readasync()。

private Task<IDataReader> ExecuteReaderAsync(IDbCommand dbCommand)
{
    var sqlCommand = CheckIfSqlCommand(dbCommand);
    PrepareExecuteReader(dbCommand);

    return Task<IDataReader>
        .Factory
        .FromAsync(sqlCommand.BeginExecuteReader, sqlCommand.EndExecuteReader, null);
}

private void ReadAll(Task<IDataReader> readerTask)
{
    var reader = readerTask.Result;

    while (reader.Read()) // Should this be asynchronously?
    {
        // Do something
    }
}

public Task<IDataReader> Foo(IDbCommand dbCommand) {
    return ExecuteReaderAsync(dbCommand)
        .ContinueWith(readerTask => ReadAll(readerTask));
}

.NET 4.5 implementation

In .NET 4.5 we can use the async/await keywords, and we can use the new asynchronous methods for SqlDataReader, like SqlDataReader.ReadAsync().

在。net 4.5中,我们可以使用异步/等待关键字,我们可以使用SqlDataReader的新异步方法,比如SqlDataReader. readasync()。

private async Task<SqlDataReader> ExecuteReaderAsync(SqlCommand dbCommand)
{
    PrepareExecuteReader(dbCommand);

    return await dbCommand.ExecuteReaderAsync();
}

private async Task ReadAll(SqlDataReader reader)
{
    while (await reader.ReadAsync()) // Should this be asynchronously?
    {
        // Do something
    }
}

public async Task<IDataReader> Foo(SqlCommand dbCommand)
{
    var reader = await ExecuteReaderAsync(dbCommand);
    await ReadAll(reader);

    return reader;
}

1 个解决方案

#1


3  

The theoretical benefit is that your application will use fewer threads, therefore consuming less memory and CPU resources on thread overhead. That, in turn, leaves more resources available for your application or other system activities, improving the performance and scalability of the application.

理论上的好处是应用程序将使用更少的线程,因此在线程开销上消耗更少的内存和CPU资源。这反过来又为应用程序或其他系统活动提供了更多的资源,从而提高了应用程序的性能和可伸缩性。

For applications that receive a lot of simultaneous requests the benefit can be significant. You can only find the actual difference that you would see by testing your specific application, though. This is a nice article that digs in to details.

对于同时接收大量请求的应用程序来说,好处是巨大的。但是,您只能通过测试特定的应用程序来发现实际的差异。这是一篇深入细节的好文章。

My opinion is that if you don't find the async DataReader code to be harder to understand, read, and debug then go ahead and use it. It will be consistent with how you handle Command code and async is generally considered a modern best practice. What do you have to lose?

我的观点是,如果您不觉得异步DataReader代码更难理解、读取和调试,那么请继续使用它。它将与如何处理命令代码保持一致,异步通常被认为是一种现代的最佳实践。你会失去什么?

I do want to mention, however, that you should really consider using a higher-level API, i.e., an ORM. I think that Entity Framework and nHibernate are the most popular for .NET currently. EF6 has built-in async support and for a typical query to be async you can simply use something like ToListAsync(). See this for a start.

但是,我想指出的是,您应该真正考虑使用更高级别的API,即。,一个ORM。我认为实体框架和nHibernate是目前。net最流行的。EF6具有内置的异步支持,对于一个典型的异步查询,您可以简单地使用ToListAsync()之类的东西。从这里开始。

#1


3  

The theoretical benefit is that your application will use fewer threads, therefore consuming less memory and CPU resources on thread overhead. That, in turn, leaves more resources available for your application or other system activities, improving the performance and scalability of the application.

理论上的好处是应用程序将使用更少的线程,因此在线程开销上消耗更少的内存和CPU资源。这反过来又为应用程序或其他系统活动提供了更多的资源,从而提高了应用程序的性能和可伸缩性。

For applications that receive a lot of simultaneous requests the benefit can be significant. You can only find the actual difference that you would see by testing your specific application, though. This is a nice article that digs in to details.

对于同时接收大量请求的应用程序来说,好处是巨大的。但是,您只能通过测试特定的应用程序来发现实际的差异。这是一篇深入细节的好文章。

My opinion is that if you don't find the async DataReader code to be harder to understand, read, and debug then go ahead and use it. It will be consistent with how you handle Command code and async is generally considered a modern best practice. What do you have to lose?

我的观点是,如果您不觉得异步DataReader代码更难理解、读取和调试,那么请继续使用它。它将与如何处理命令代码保持一致,异步通常被认为是一种现代的最佳实践。你会失去什么?

I do want to mention, however, that you should really consider using a higher-level API, i.e., an ORM. I think that Entity Framework and nHibernate are the most popular for .NET currently. EF6 has built-in async support and for a typical query to be async you can simply use something like ToListAsync(). See this for a start.

但是,我想指出的是,您应该真正考虑使用更高级别的API,即。,一个ORM。我认为实体框架和nHibernate是目前。net最流行的。EF6具有内置的异步支持,对于一个典型的异步查询,您可以简单地使用ToListAsync()之类的东西。从这里开始。