I can go on about two ways in declaring/consuming an async method. Let's see...
Way 1
Let's say I have a method (declaration)
Class MyClass
{
...
protected IDbSet<TEntity> IDbSet;
...
public virtual Task<TEntity> GetFirstOrDefaultAsync(Expression<Func<TEntity, bool>> predicate)
{
return IDbSet.FirstOrDefaultAsync(predicate);
}
}
(consumption)
public async Task<MyViewModel> GetItemByNumber(int itemNumber)
{
var model = await GetFirstOrDefaultAsync(c => c.ItemNumber == itemNumber);
if (model == null)
return new MyViewModel();
return AutoMapper.Mapper.Map<Model, MyViewModel>(model);
}
Way 2
(declaration)
Class MyClass
{
...
protected IDbSet<TEntity> IDbSet;
...
public virtual async /* added this here */ Task<TEntity> GetFirstOrDefaultAsync(Expression<Func<TEntity, bool>> predicate)
{
// now returning the awaited result
return await /*added here*/ IDbSet.FirstOrDefaultAsync(predicate);
}
}
(consumption)
public async Task<MyViewModel> GetItemByNumber(int itemNumber)
{
var model = await GetFirstOrDefaultAsync(c => c.ItemNumber == itemNumber);
if (model == null)
return new MyViewModel();
return AutoMapper.Mapper.Map<Model, MyViewModel>(model);
}
Now, as you can see, I am consuming the method same way in both the cases, but I have declared them differently. In the first one, I am returning the task, in the second one, I am returning the awaited result I am not sure which one is actually async (or if they both are). To make it even more confusing, visual studio intellisense says, (in both the cases) awaitable.
So I wanna know,
1) What is the difference in both version?
2) Is one of them faster/slower compared to the other?
3) Which one is preferred and why?
4) Are they both async (I am guessing the answer to this would be yes, but just to be sure)
EDIT/UPDATE
I've read the question, to which this was marked as duplicate. I've gone through this, this one, and this one as well. Although they did help me clear a few issue, there are still some bits that are unclear.
1) I understand the differnce is in disposing pattern. Deadlocking and exception handling.
2) Acccording to some answers, (of course, only under certain circumstances) the task version should compile/run fast.
3) The answer to first question (regardning exception handling, and posting on the synchronization context should be the factor in figuring this out, also, along with if you need to await on some other task in the same method as well, as expalined in this answer)
4) I am still not clear on this one. According to this answer, (second point) the first one (way 1) is not aysnc, while the second one is. I also tried to read the article mentioned in the answer, but still couldn't get a clear understanding of how the first one will not execute asynchronously. If anyone can help me understand this last missing piece of puzzle that'd be great.