There is no way to run a synchronous method other than synchronously.
You can wrap the result in something that looks like it was run asynchronously (eg. Task.FromResult), or run in another thread.1 But the synchronous method will still block the thread it is running on.
(The reverse, blocking on an asynchronous operation, is trivial. This is why you need to have the underlying operations asynchronous because you can build both synchronous and asynchronous methods on top.)
Update (for update in question):
That additional code – specifically the task.Wait() statement – will cause the caller's thread to block while waiting for the task to complete. That task will run on another thread causing that thread to block. Ie. you are causing two threads (caller, and a thread pool thread) to block. If the underlying method was called directly only the caller's thread would be blocked.
You have two approaches:
Best: use ADO.NET's asynchronous operations. (This means not using DataTables/DataAdaptor but IMHO that's a good move anyway: all they do is move operations that should be done on the database into the client.)
Offload to another thread, but return a Task<TResult> to the caller, only marking the Task as complete then the underlying operation is complete. Something like:
protected override Task<bool> GetData(params object[] getDataParams) { var tcs = new TaskCompletionSource<bool>(); Task.Factory.StartNew(async () => { using (var adapter = new DataAdapter()) { // Take your time and fetch the data tcs.SetResult(the-result); } }); return tcs.Task; }
Note here the return from GetData is a Task<bool>: the caller needs to either wait or do something else concurrently and then get the result of the data operation. If the caller just waits then you have two blocked threads. (C# 5's await is different: the caller also becomes asynchronous.)
1 For the avoidance of doubt: this can be made to look like a normal, Task<T> returning, asynchronous method (eg. making use of TaskCompletionSource<T> off loading the blocking from the current thread to some thread in the thread pool). But it is still a blocking operation: just blocking a different thread.
awaitthe task or similar. The method in your abstract class is synchronous by definition so unless you can change that you're out of luck.ExecuteReaderAsyncandExecuteNonQueryAsync. ORMs like EF and microORMs like Dapper also provide asynchronous methods. Most likely your actual data access code can be modified to run asynchronously.GetDataso it, too, returns a task (either by returning the wrapped task directly or using async/await) - you'll need to do this all the way up to your UI otherwise the UI thread will still be blocked somewhere down the line.