I have made a lightweight mediator kind of library for use internally.
A query can be mapped to a async method without the caller knowing anything about it.
public interface IMediator
{
TResult ExecuteQuery<TResult>(Query<TResult> query);
Task<TResult> ExecuteQueryAsync<TResult>(Query<TResult> query);
Task ExecuteCommandAsync(Command command);
Task<TResult> ExecuteCommandAsync<TResult>(Command<TResult> command);
void ExecuteCommand(Command command);
TResult ExecuteCommand<TResult>(Command<TResult> command);
void EnqueueTask(object task);
}
public abstract class Query<TResult> { }
public interface IQueryHandler<Query, TResult> where Query : Query<TResult>
{
TResult Handle(Query param);
}
public interface IAsyncQueryHandler<Query, TResult> where Query : Query<TResult>
{
Task<TResult> Handle(Query param);
}
When the caller is in a sync thread e.g factory method in the service container and want to execute a query it can not do that async using the ExecuteQueryAsync but the actual handler of the query, implementing the IAsyncQueryHandler is async.
So I need to call async over sync.
I do some reflection a registration time to actually figure out how to call the handler, I tried the .wait() and .result() but I get thread locks.
current code looks like this.
private object AsyncSync(object service, object param)
{
dynamic t = Method.Invoke(service, new[] { param });
return t.GetAwaiter().GetResult();
}
The Method is the method info from reflection, and the service is an instance of the class with that method.
This code still gives me deadlock of threads.
How could I achieve this with, do I need to look into the task factory? Any suggestions?