I have the following function in a .NET Core 2.0 app.
public DataTable CallDb(string connStr, string sql)
{
var dt = new DataTable();
var da = new Sq
SqlDataAdapter
was never updated to include the TPL version of the methods. You could do this:
await Task.Run(() => da.Fill(dt));
But that would be creating a thread that would do nothing useful.
A good approach would be to use something like this:
public async Task<DataTable> CallDb(string connStr, string sql)
{
var dt = new DataTable();
var connection = new SqlConnection(connStr);
var reader = await connection.CreateCommand().ExecuteReaderAsync();
dt.Load(reader);
return dt;
}
Of course, some changes like using
statements should be made. However, here you are using asynchronous calls the right way.
Although the initial call to ExecuteReaderAsync()
will not block in this case, dt.Load(reader)
probably does the equivalent of reader.Read()
rather than await reader.ReadAsync()
, and may block the calling thread while retrieving rows.
If you do need a DataTable
for use with an external API, or because you don't know the field definitions in advance, but require fully asynchronous behaviour, you might be better off to use your own code to construct a DataTable
, add the required columns e.g. based on reader.GetName()
and reader.GetFieldType()
, and then populate it with rows in a loop using await reader.ReadAsync()
and dt.Rows.Add()
.