IDbCommand接口缺少异步功能

时间:2014-10-01 20:33:28

标签: c# asynchronous idbcommand

这是向IDbCommand接口添加异步功能的合理方法吗?

public async static Task<IDataReader> ExecuteReaderAsync(this IDbCommand self) {
    DbCommand dbCommand = self as DbCommand;
    if (dbCommand != null) {
        return await dbCommand.ExecuteReaderAsync().ContinueWith(task => (IDataReader)task.Result);
    } else {
        return await Task.Run(() => self.ExecuteReader());
    }
}

具体来说,我并不完全确定使用&#34; ContinueWith&#34;伪造&#34;任务&#34;的协方差。

此外,在不太可能的情况下,来自&#34; self&#34;实例不从DbCommand继承,在执行&#34; self.ExecuteReader()&#34;?

期间是否会消耗和阻塞线程池线程

在这里a link完全实现了异步支持的IDb扩展。

谢谢

2 个答案:

答案 0 :(得分:3)

如果您使用的是.NET 4.5,则缺少asyncawait。你尝试的方式是正确的,希望你分别处理连接。

public static async Task<IDataReader> ExecuteReaderAsync(this IDbCommand self)
{
    var dbCommand = self as DbCommand;
    if (dbCommand != null)
    {
        return await dbCommand.ExecuteReaderAsync();
    }

    return await Task.Run(() => self.ExecuteReader());
}

答案 1 :(得分:3)

只是因为它更干净,我会利用你使用asyncawait取消ContinueWith()中的广告投放这一事实。 awaitTResult上使用时,Task<TResult>会评估为return (IDataReader)await dbCommand.ExecuteReaderAsync();类型的对象。我打算建议语法DbDataReader,但后来我记得编译器已经知道IDataReaderawait。在VS 2013和VS 2015 Preview中测试过(不确定您的目标是什么,但我认为所有支持public async static Task<IDataReader> ExecuteReaderAsync(this IDbCommand self) { DbCommand dbCommand = self as DbCommand; if (dbCommand != null) { return await dbCommand.ExecuteReaderAsync(); } else { return await Task.Run(() => self.ExecuteReader()); } } 的C#编译器都应该使用此功能):

await

现在,您正在使用self as DbCommand来发挥更大的潜力并节省几个字节的代码; - )。

此实现的最大问题当然是IDbCommand中的运行时类型测试。在我看来,DbCommand should be used instead of IDbCommand。这将允许您删除运行时强制转换。但是,如果将所有内容从DbCommand切换到is并且运行时类型检查可能性能不足,则可能不会编写此库。

Visual Studio 2017语法

使用较新版本的C#,您可以使用as关键字代替public async static Task<IDataReader> ExecuteReaderAsync(this IDbCommand self) { if (self is DbCommand dbCommand) { return await dbCommand.ExecuteReaderAsync(); } else { return await Task.Run(() => self.ExecuteReader()); } } 来编写更简洁的代码:

{{1}}