I'm writing a C# .Net 4.5 library for doing common sql database operations (backup, restore, execute script, etc.). I want to have both synchronous and asynchronous functions for each operation, as this library will be used by both console and GUI apps, but I don't want to duplicate code everywhere. So as I see it, I have two options:
Write the code that does the work in a synchronous function, and then just wrap it in a task for the async function, like so:
public void BackupDB(string server, string db)
{
// Do all of the work and long running operation here
}
public async Task BackupDBAsync(string server, string db)
{
await Task.Factory.StartNew(() => BackupDB(server, db)).ConfigureAwait(false);
}
Write the code that does the work in an asynchronous function, and call it from a synchronous function using .Wait():
public async Task BackupDBAsync(string server, string db)
{
// Do all of the work and long running operation here, asynchronously.
}
public void BackupDB(string server, string db)
{
BackupDBAsync(server, db).Wait(); // Execution will wait here until async function finishes completely.
}
Is one option better than the other? Is one a best practice? Or are there any other (better) alternatives?
I know that one caveat to using .Wait() is that all of the await statements in the async function have to use .ConfigureAwait(false) to avoid deadlocks (as discussed here), but since I'm writing a library that will never need to access the UI or WebContext I am safe to do that.
I'll note too that the SQL library typically also has both synchronous and async functions that can be used, so if doing the work in the sync function, I would call their sync function, and if doing the work in the async function, I would call their async function.
Thoughts/suggestions are appreciated.
-- edit: I've also posted this question on the MSDN forums here to try and get an official MS response --
I want to have both synchronous and asynchronous functions for each operation, as this library will be used by both console and GUI apps, but I don't want to duplicate code everywhere.
The best answer is: don't.
Stephen Toub has two excellent blog posts on this topic:
He recommends exposing asynchronous methods as asynchronous, and synchronous methods as synchronous. If you need to expose both, then encapsulate common functionality in private (synchronous) methods, and duplicate the async/sync differences.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With