如何在 C# 中等待事件处理程序的响应?
How to wait for the response of event handler in C#?
我有一个分为多个层的应用程序 (A1)。一些层用于用户交互,一些用于与不同的数据库交互,一些包含业务逻辑。我们有另一个第三方应用程序 (A2) 向 (A1) 发送请求,A1 需要响应该请求。下面是A1的架构。
T3(该层接收来自 A2 应用程序的请求)
T2(业务逻辑)
T1(用户界面)
T2 包含所有业务逻辑。我面临的问题是当我收到来自 A2 应用程序的请求时。我需要根据 T2 中存在的一些业务逻辑对请求做出响应。我可以从 T3 调用 T2 订阅的事件,但我必须从事件处理程序获取数据,如下所示;
T3:
public Response CanStore(string materialType){
//Invoke event and wait to get response from T2
return response.;
}
T2:订阅了T3的事件
public async void canStore(object sender, EventArgs e){
//Perform some logic and response result to T3
}
可能吗?
在我看来你的架构是错误的
如果 T2 有业务逻辑,T1 是一个用户界面,大概需要访问业务逻辑,T3 是一个从外部接收消息的应用程序,也需要访问业务逻辑,那么 T1 和 T3 都需要引用 T2。
那么这只是将业务逻辑依赖注入到 T3 中的简单一点!
public class T3Service
{
private readonly IT2BusinessLogic businessLogic;
public T3Service(IT2BusinessLogic businessLogic)
{
this.businessLogic = businessLogic;
}
public Response CanStore(string materialType)
{
var t2Response = businessLogic.CanStore(materialType);
// Do what you like to build response to external service
return response;
}
}
除了体系结构问题之外,假设您可以修改 T3 和 T2,您可以通过一些自定义 EventType 来解决滥用 EventArgs 的问题。不是我最喜欢的,但可以解决你的问题。
让T2操作EventArg,把需要的结果存入里面。
事件处理程序完成后,调用站点 T3 可以从 eventArg 获取结果。
类似
public Response CanStore(string materialType){
//Invoke event and wait to get response from T2
myEvent.Invoke?(sender, myCustomEventArgs);
await myCustomEvent.Completion.Task;
return myCustomEvent.ResponseFromSubscriber;
}
使用 myCustomEvent 使用两个属性扩展您当前的事件,
MyCustomEventArgs: MyCurrentEventArgs
{
// makes your Event "awaitable";
TaskCompletionSource<bool> Completion{ get; } = new TaskCompletionSource<bool>;
Response ResponseFromSubscriber{ get; set; } // As you need
}
和订阅者
public async void canStore(object sender, EventArgs e){
//Perform some logic and response result to T3
if(e is MyCustomEventArgs myCustomEventArgs)
{
myCustomEventArgs.ResponseFromSubscriber = new Reponse(); // Your whatever
myCustomEventArgs.Completion.SetResult(true); // Triggers the Task completion for your awaiting EventInvoker
}
}
我有一个分为多个层的应用程序 (A1)。一些层用于用户交互,一些用于与不同的数据库交互,一些包含业务逻辑。我们有另一个第三方应用程序 (A2) 向 (A1) 发送请求,A1 需要响应该请求。下面是A1的架构。
T3(该层接收来自 A2 应用程序的请求)
T2(业务逻辑)
T1(用户界面)
T2 包含所有业务逻辑。我面临的问题是当我收到来自 A2 应用程序的请求时。我需要根据 T2 中存在的一些业务逻辑对请求做出响应。我可以从 T3 调用 T2 订阅的事件,但我必须从事件处理程序获取数据,如下所示;
T3:
public Response CanStore(string materialType){
//Invoke event and wait to get response from T2
return response.;
}
T2:订阅了T3的事件
public async void canStore(object sender, EventArgs e){
//Perform some logic and response result to T3
}
可能吗?
在我看来你的架构是错误的
如果 T2 有业务逻辑,T1 是一个用户界面,大概需要访问业务逻辑,T3 是一个从外部接收消息的应用程序,也需要访问业务逻辑,那么 T1 和 T3 都需要引用 T2。
那么这只是将业务逻辑依赖注入到 T3 中的简单一点!
public class T3Service
{
private readonly IT2BusinessLogic businessLogic;
public T3Service(IT2BusinessLogic businessLogic)
{
this.businessLogic = businessLogic;
}
public Response CanStore(string materialType)
{
var t2Response = businessLogic.CanStore(materialType);
// Do what you like to build response to external service
return response;
}
}
除了体系结构问题之外,假设您可以修改 T3 和 T2,您可以通过一些自定义 EventType 来解决滥用 EventArgs 的问题。不是我最喜欢的,但可以解决你的问题。
让T2操作EventArg,把需要的结果存入里面。 事件处理程序完成后,调用站点 T3 可以从 eventArg 获取结果。
类似
public Response CanStore(string materialType){
//Invoke event and wait to get response from T2
myEvent.Invoke?(sender, myCustomEventArgs);
await myCustomEvent.Completion.Task;
return myCustomEvent.ResponseFromSubscriber;
}
使用 myCustomEvent 使用两个属性扩展您当前的事件,
MyCustomEventArgs: MyCurrentEventArgs
{
// makes your Event "awaitable";
TaskCompletionSource<bool> Completion{ get; } = new TaskCompletionSource<bool>;
Response ResponseFromSubscriber{ get; set; } // As you need
}
和订阅者
public async void canStore(object sender, EventArgs e){
//Perform some logic and response result to T3
if(e is MyCustomEventArgs myCustomEventArgs)
{
myCustomEventArgs.ResponseFromSubscriber = new Reponse(); // Your whatever
myCustomEventArgs.Completion.SetResult(true); // Triggers the Task completion for your awaiting EventInvoker
}
}