Issue
I want to implement an interface that has a Run method:
public interface IRunner
{
bool Run();
}
But the issue I am facing is that some Run functions should be synchronous and some should be asynchronous. One solution would be to implement two interfaces:
public interface IRunner
{
bool Run();
}
public interface IRunnerAsync
{
Task<bool> RunAsync();
}
But the issue here is, that if I have, say, a list of objects implementing these interfaces, I will have to always make a check of what type each object is before calling the method, which feels hacky. What would be best practices to implement interfaces like these?
Solution
Perhaps just have the async version, and accept that some callers may implement it internally in a synchronous fashion; they can do this locally and just return the true
/false
as a wrapped task via Task.FromResult
, noting that (at least in current frameworks) the runtime will special-case the bool
case, and avoid allocating multiple tasks internally (the details aren't important). Your consumption code can just await
an already-completed synchronous result, and everything will keep working. In some very specific scenarios (usually in library code), it may be beneficial for your consumption code to explicitly test for synchronously-completed results, and optimize away some of the async
overheads.
In a more general Task<T>
scenario, where you don't want the synchronous implementations to have to allocate, consider switching to ValueTask<T>
instead; with that API, synchronous implementations can return a new ValueTask<TheType>(value)
without allocating, and asynchronous versions can either wrap a Task<T>
, or can simply declare themselves as async ValueTask<T> Whatever()
and let the compiler worry about the details. There is also a third way of implementing ValueTask<T>
, for niche async low-allocation scenarios, but: that's probably overkill here. One caveat with ValueTask[<T>]
: a value-task should only be awaited once (or rather: the outcome should only be retrieved once).
Answered By - Marc Gravell Answer Checked By - Pedro (PHPFixing Volunteer)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.