我为内部使用制作了一种轻量级的中介者库。
一个查询可以映射到一个异步方法,而调用方不需要知道任何信息。
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);
}
当调用者在同步线程中,例如服务容器中的工厂方法并希望执行查询时,它不能使用
ExecuteQueryAsync
异步执行查询,但查询的实际处理程序,即实现了IAsyncQueryHandler
接口的处理程序,是异步的。所以我需要在同步代码中调用异步代码。
我在注册时使用反射来确定如何调用处理程序,我尝试过使用.wait()和.result()但会出现线程锁死。
当前的代码如下。
private object AsyncSync(object service, object param)
{
dynamic t = Method.Invoke(service, new[] { param });
return t.GetAwaiter().GetResult();
}
Method
是反射中的方法信息,service
是该方法所在类的实例。
这段代码仍然导致线程死锁。
我该如何实现它?我需要查看任务工厂吗?有什么建议吗?