简体   繁体   中英

How to wait for the response of event handler in C#?

I have an application (A1) which is divided into multiple tiers. Some tiers are used for user interactions, some are used to interact with different databases and some included the business logic. We have another third party application (A2) which sends a request to (A1) and A1 needs to response against the request. Below is the architecture of A1.

T3 (This tier receives the request from A2 application)

T2 (Business logic)

T1 (User Interface)

T2 contains all the business logic. The problem I am facing is when I receive request from the A2 application. I need to respond against request on the basis of some business logic which presents in T2. I can invoke the event from T3 that is subscribed by T2 but I have to get data from the event handler like below;

T3:

public Response CanStore(string materialType){
    //Invoke event and wait to get response from T2
    return response.;

}

T2: Subscribed the event of T3

 public async void canStore(object sender, EventArgs e){
     //Perform some logic and response result to T3
}

Is it possible?

It sounds to me like you have your architecture the wrong way round

If T2 has business logic, and T1 is a User interface which presumably needs access to the business logic and T3 is an application which receives messages from an external party and also needs access to the business logic, then both T1 & T3 need a reference to T2.

Then this is just a simple bit of Dependency Injection of the business logic into 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;

    }
}

Aside from the architectural issues and assuming you can modify T3 and T2, you can workaround abusing the EventArgs with some custom EventType. NOT my favorite but could solve your issue.

Let T2 manipulate the EventArg to store the required result inside. After completion of your Eventhandler the calling site T3 can fetch the result from the eventArg.

Something like

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;
}

with myCustomEvent extending your current Event with two Properties,

MyCustomEventArgs: MyCurrentEventArgs
{
    // makes your Event "awaitable";
    TaskCompletionSource<bool> Completion{ get; } = new TaskCompletionSource<bool>; 
    Response ResponseFromSubscriber{ get; set; } // As you need 
}

and the subscriber

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
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM