patterncsharpMinor
Writing highly asynchronous code
Viewed 0 times
asynchronouscodehighlywriting
Problem
I am writing a new web service that will be performing a lot of large data load operations. To do so I am moving the data to a temporary table then merging the data in to the live data via a stored procedure.
That part I have down and working and am very confident in. What I am doing now is trying to optimize the loading code to help take the load off of the IIS server that will be performing these operations.
Here is what I am currently doing synchronously and works fine.
And here is my attempt at translating that in to asynchronous code.
```
public async Task BulkLoadDataAsync(IDataReaderWithMappings reader,
string createTempTableStatement,
string loadingStoredProcedureName)
{
using (var connection = new SqlConnection(_connectionString))
using (var bulkCopy = new SqlBulkCopy(connection))
using (var command = new SqlCommand(createTempTableStatement))
{
var firstStage = connection.OpenAsync()
.ContinueWith(async delegate
{
await co
That part I have down and working and am very confident in. What I am doing now is trying to optimize the loading code to help take the load off of the IIS server that will be performing these operations.
Here is what I am currently doing synchronously and works fine.
public void BulkLoadData(IDataReaderWithMappings reader,
string createTempTableStatement,
string loadingStoredProcedureName)
{
using (var connection = new SqlConnection(_connectionString))
using (var bulkCopy = new SqlBulkCopy(connection))
using (var command = new SqlCommand(createTempTableStatement, connection))
{
connection.Open();
command.ExecuteNonQuery();
bulkCopy.DestinationTableName = "#temp";
var mappings = reader.GetMappings();
foreach (var sqlBulkCopyColumnMapping in mappings)
{
bulkCopy.ColumnMappings.Add(sqlBulkCopyColumnMapping);
}
bulkCopy.WriteToServer(reader);
command.CommandType = CommandType.StoredProcedure;
command.CommandText = loadingStoredProcedureName;
command.ExecuteNonQuery();
}
}And here is my attempt at translating that in to asynchronous code.
```
public async Task BulkLoadDataAsync(IDataReaderWithMappings reader,
string createTempTableStatement,
string loadingStoredProcedureName)
{
using (var connection = new SqlConnection(_connectionString))
using (var bulkCopy = new SqlBulkCopy(connection))
using (var command = new SqlCommand(createTempTableStatement))
{
var firstStage = connection.OpenAsync()
.ContinueWith(async delegate
{
await co
Solution
If you want to combine
But using
And then in the main method:
Another option would be use a lambda instead of the helper method:
ContinueWith() and async this way, then you need to use Unwrap(). (And it is available, though my ReSharper doesn't seem to think so, maybe you use that too?) If you don't do that, you're not actually waiting for ExecuteNonQueryAsync() to complete.But using
ContinueWith() is usually not a good idea when you can use await. Instead, you can use a helper method:private static async Task FirstStageAsync(SqlConnection connection, SqlCommand command)
{
await connection.OpenAsync().ConfigureAwait(false);
await command.ExecuteNonQueryAsync().ConfigureAwait(false);
}And then in the main method:
var firstStage = FirstStageAsync(connection, command);
…
//Wait for the connection opening and the create table task to finish.
await firstStage.ConfigureAwait(false);Another option would be use a lambda instead of the helper method:
Func firstStageFunc = async () =>
{
await connection.OpenAsync().ConfigureAwait(false);
await command.ExecuteNonQueryAsync().ConfigureAwait(false);
};
var firstStage = firstStageFunc();Code Snippets
private static async Task FirstStageAsync(SqlConnection connection, SqlCommand command)
{
await connection.OpenAsync().ConfigureAwait(false);
await command.ExecuteNonQueryAsync().ConfigureAwait(false);
}var firstStage = FirstStageAsync(connection, command);
…
//Wait for the connection opening and the create table task to finish.
await firstStage.ConfigureAwait(false);Func<Task> firstStageFunc = async () =>
{
await connection.OpenAsync().ConfigureAwait(false);
await command.ExecuteNonQueryAsync().ConfigureAwait(false);
};
var firstStage = firstStageFunc();Context
StackExchange Code Review Q#44547, answer score: 3
Revisions (0)
No revisions yet.