Suppose I have a method as follows...
public static async Task DoIt(Func<Task> doit) {
// Do something first
await doit();
// Do something last
}
I can pass in an awaitable function as follows...
await DoIt(() => Task.Delay(1000));
If I want to pass in something non-awaitable, I can do it like this...
_ = DoIt(() => Task.Run(() => Console.WriteLine("Hi")));
...but this seems quite ugly. Is there a neater way of doing this?
CodePudding user response:
If the action is an async, non-awaitable method (e.g. async void
) there isn't really a proper way to return a task. There is no way to return a task that signals its completion when the async void method finishes.
If the action is a synchronous method, you can just return Task.CompletedTask
.
_ = DoIt(() => { Console.WriteLine("Hi"); return Task.CompletedTask; } );
CodePudding user response:
You could consider adding a DoIt
overload that has an Action
parameter, and delegates to the primary DoIt(Func<Task>)
:
public static Task DoIt(Action action)
=> DoIt(() => { action(); return Task.CompletedTask; });
The action
is captured by the () =>
lambda, so this approach has a minuscule overhead (a small object is heap-allocated on each call).
Be aware that the action
will be invoked on the context of the caller. It might be invoked on the same thread that invoked the DoIt
, and depending on the specifics of the code block // Do something first
it might even be invoked synchronously.