如何在 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
    }
}