2014-10-01 123 views
3

這是將異步功能添加到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

回答

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

只是因爲它是清潔的,我會採取的事實,即你正在使用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之間的切換沒有問題,並且運行時類型檢查可能具有足夠的性能,那麼您可能不會寫入該庫。