3
votes

In my data access layer I'm attempting to create methods with return types of Task.

I cannot get the return type from the entity framework to return Task<List<MYtype>>

   public static Task<List<ILeaf>> GetLeafs(int doorID)
    {
        using (var db = new StorefrontSystemEntities())
        {
            return db.proc_GetDoorLeafs(doorID).ToList<ILeaf>();
        };
    }

Is the only way to make this run correctly is to format the code like so:

 public async static Task<List<ILeaf>> GetLeafs(int doorID)
    {
        return await Task.Run(() =>
            {
                using (var db = new StorefrontSystemEntities())
                {
                    return db.proc_GetDoorLeafs(doorID).ToList<ILeaf>();
                };
            });
    }

The reason I was asking is because I would like to give the option to run async, or am I not understanding this correctly? If I can just return a Task then on the calling end I could give the option to await if I wanted to run async, but if i wanted to run synchronously I would just call the method as normal.

If I'm returning a Task do I always have to include the async keyword in the method signature?

Am I thinking about this the wrong way? If I've got a return type of Task then the method has the option of being called async or synchronously?

But, if I have async and Task in the method signature then the method runs async no matter what?

Thanks!

2

2 Answers

13
votes

So to answer the literal question asked, you can just do this:

public static Task<List<ILeaf>> GetLeafs(int doorID)
{
    return Task.Run(() =>
        {
            using (var db = new StorefrontSystemEntities())
            {
                return db.proc_GetDoorLeafs(doorID).ToList<ILeaf>();
            };
        });
}

That said, note that this isn't a particularly useful method. The idea of leveraging asynchronous programming is that you don't want to have a thread pool thread sitting there doing nothing but waiting on this IO operation. Ideally you'd leverage IO that is inherently asynchronous in nature; a method that itself naturally returns a task.

You aren't really providing value to consumers of your code by wrapping the blocking IO in a call to Task.Run. If they need that operation to be run in a background thread they can do so on their own, and then they'll know more precisely that it's not a naively asynchronous operation.

See Should I expose asynchronous wrappers for synchronous methods? for more information on the subject.

7
votes
public static async Task<List<ILeaf>> GetLeafs(int doorID)
{
    using (var db = new StorefrontSystemEntities())
    {
        var result = db.proc_GetDoorLeafs(doorID).ToList<ILeaf>();
        return await Task.FromResult(result);
    }
}