Friday, September 14, 2012

Return a Task From BeginExecuteNonQuery

Blog as notepad time. Just a little reminder for myself on how to return the result from BeginExecuteNonQuery as a Task<int>

public Task<int> Save(string value)
{
var taskCompletionSource = new TaskCompletionSource<int>();

var connection = new SqlConnection(connectionString);
connection.Open();
var command = new SqlCommand("uspSaveSomeValue", connection)
{
CommandType = CommandType.StoredProcedure
};
command.Parameters.AddWithValue("@myparam", value);
command.BeginExecuteNonQuery(asyncResult =>
{
var result = command.EndExecuteNonQuery(asyncResult);
command.Dispose();
connection.Dispose();
taskCompletionSource.SetResult(result);
}, null);

return taskCompletionSource.Task;
}

If you know a better way, please comment below.

Yes, yes, I know, but I’m not working on 4.5 yet  :(

Update: Ken Egozi suggested using Task<int>.Factory.FromAsync. Of course! I’d been doing so much TaskCompletionSource manual task creation recently that I’d forgotten about this useful shortcut. Here’s a more succinct version using FromAsync:

public Task<int> Save(string value)
{
var connection = new SqlConnection(connectionString);
connection.Open();
var command = new SqlCommand("uspSaveSomeValue", connection)
{
CommandType = CommandType.StoredProcedure
};
command.Parameters.AddWithValue("@myparam", value);

return Task<int>.Factory.FromAsync(command.BeginExecuteNonQuery(), asyncResult =>
{
var result = command.EndExecuteNonQuery(asyncResult);
command.Dispose();
connection.Dispose();
return result;
});
}

5 comments:

Anonymous said...

Not disposing in case the End* call fails.

Ken Egozi said...

I'm not with access to any dev machine to test it so it might be completely silly of me, but would not Task.Factory.FromAsync work here?

Anonymous said...

Hi Mike,

why would you want an async save - is this for a desktop app?

Anonymous said...

also what about exceptions?

Mike Hadlow said...

You'd use this any time to wanted the free the thread making the call. In my case a high-performance web application.

Exceptions should be handled by task's consumer.