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:

  1. Anonymous9:43 pm

    Not disposing in case the End* call fails.

    ReplyDelete
  2. 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?

    ReplyDelete
  3. Anonymous9:24 pm

    Hi Mike,

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

    ReplyDelete
  4. Anonymous9:26 pm

    also what about exceptions?

    ReplyDelete
  5. 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.

    ReplyDelete

Note: only a member of this blog may post a comment.