I'm still learning async/await concepts so please bear with me. Suppose there is this legacy code that defines a contract for getting data from a data source (local database in the real case):
public interface IRepository<T> {
    IList<T> GetAll();
}
In new code I have the following interface:
public interface IMyObjectRepository {
    Task<IEnumerable<MyObject>> GetAllAsync();
}
The MyObjectRepository class depends on IRepository<T> like this:
public class MyObjectRepository : IMyObjectRepository
{
    private readonly IRepository<Some.Other.Namespace.MyObject> repo_;
    private readonly IDataMapper<Some.Other.Namespace.MyObject, MyObject> mapper_;
    public BannerRepository(IRepository<Some.Other.Namespace.MyObject> repo, IDataMapper<Some.Other.Namespace.MyObject, MyObject> mapper)
    {
        repo_ = repo;
        mapper_ = mapper;
    }
}
How do I implement the IMyObjectRepository.GetAllAsync() method in such a way that it makes sense in the context of asynchronous programming? Getting data from some local data source is an I/O bound operation, so the way I did it is:
public async Task<IEnumerable<MyObject>> GetAllAsync()
{
    var tcs = new TaskCompletionSource<IEnumerable<MyObject>>();
    try
    {
        GetAll(objects =>
        {
            var result = new List<MyObject>();
            foreach (var o in objects)
            {
                result.Add(mapper_.Map(o));
            }
            tcs.SetResult(result);
        });
    }
    catch (Exception e)
    {
        tcs.SetException(e);
    }
    return await tcs.Task;
}
private void GetAll(Action<IEnumerable<Some.Other.Namespace.MyObject>> handle)
{
    IEnumerable<Some.Other.Namespace.MyObject> objects = repo_.GetAll<Some.Other.Namespace.MyObject>();
    if (objects is null)
    {
        objects = Enumerable.Empty<Some.Other.Namespace.MyObject>();
    }
    handle(objects);
}
Does this make any sense? I did not want to use Task.Run() because, the way I understand it, that wastes a thread for nothing in the case of an I/O bound operation which makes sense.
 
     
    