In short, if the base class or interface is expecting a Task result and you have synchronous method and it doesn't need to run in a task, all you need to do is give it a pre-completed task.
The simplest thing to do, would be just leave the async keyword, return the result, and ignore (or pragma out) the warning. You do not need to spin-up a new task via Task.Run (this would be an inefficient way of achieving nothing). In this case the compiler automatically takes care of everything for you (albeit with a warning that you have nothing to await)
protected override async Task<TResult> OnExecuteAsync<TResult>()
{
return DoSomething();
}
You could also use Task.FromResult to create the pre-completed task. The only caveat is if the consumer is calling await, in which case you should be nice and make sure any exceptions are returned on the resulting Task with Task.FromException. This is analogous to what the compiler generated IAsyncStateMachine implementation (async and await pattern) would automatically do.
protected override Task<TResult> OnExecuteAsync<TResult>()
{
try
{
return Task.FromResult(DoSomething());
}
catch(exception ex)
{
// place any exception on the returned task
return Task.FromException<TResult>(ex);
}
}