IDbCommand接口中缺少异步功能

问题描述:

这是将异步功能添加到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()); 
    } 
} 

具体而言,我不完全确定使用“ContinueWith”来伪造“任务”的协方差的效果。

此外,传入的“self”实例不会从DbCommand继承,在执行“self.ExecuteReader()”期间是否会消耗和阻塞线程池线程?

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

谢谢

+0

你打算把你的图书馆作为nuget包吗? – binki 2014-12-30 16:01:33

你,如果你使用的是.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()); 
} 

只是因为它是清洁的,我会采取的事实,即你正在使用asyncawait废除在ContinueWith()投。当在Task<TResult>上使用时,await评估类型为TResult的对象。我打算建议语法return (IDataReader)await dbCommand.ExecuteReaderAsync();,但后来我记得编译器已经知道DbDataReaderIDataReader。经测试,在VS 2013和VS 2015年预览(不知道你的目标是什么,但我认为支持await应与此工作的所有C#编译器):

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()); 
    } 
} 

您现在使用的await其更充分的潜力和节省了几个字节的代码;-)。

该实现最大的问题当然是运行时类型测试self as DbCommand。如果从IDbCommandDbCommand之间的切换没有问题,并且运行时类型检查可能具有足够的性能,那么您可能不会写入该库。