'Best practice async base method signature [closed]
I've been wondering about this for quite some time, but didn't find any clear answer to this problem.
We're working on a WPF application with Entity Framework (C#). We've got a generic base class for a list component with some methods, like LoadData.
Currently its signature is abstract List<TItem> LoadData(), which means you can't use async await in there without losing control of the execution flow (other methods could potentially start before LoadData finished, creating a race condition).
Entity Framework has an extension method ToListAsync() which asynchronously fetches the data. Pretty much every component would be able to use this inside of LoadData.
Therefore, this method is a great candidate to be refactored to a signature of abstract Task<List<TItem>> LoadDataAsync().
However, there are other methods on the base class which aren't quite as straight forward. Most of the time they are overwritten, async isn't required. However, sometimes (like 1/20) it'd be very useful if the method would return Task/Task<T> instead of just void/T.
Every other time that'd mean I'd need to return Task.CompletedTask/to wrap the result of the method in a Task.FromResult(result).
An example for this kind of method would be abstract TItem AddItem(someParameters), which most of the time simply creates a new object with parameters from a form. Sometimes though, you need additional data from a database or something similar. In those cases you'd need the base methods' signature to be abstract Task<TItem> AddItemAsync(someParameters). (Edit: this idea really sucks, for multiple reasons)
Is there any reason to prefer a signature without Task in situations where performance isn't a big issue? Those methods will only be called once per module, adding Task to the signature wouldn't have a big impact on performance.
Another idea would be to offer both a normal base method and an async one, but that'd result in a lot of bloat and is probably just a bad idea.
TL;DR: Is there any reason not to return Task/Task<T> (or ValueTask<T>) in base methods, even if async is rarely used in the actual implemetation and most of the time I'd have to return Task.CompletedTask/Task.FromResult(result)?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
