Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wait for another method to invoke and then continue with result

Tags:

c#

invoke

I am trying to invoke a method from another .dll file . It is sending a message through the VPN then Return the RecievedMessage from another computer.

As you now it takes time to sending and receiving message and VpnObject just send message and I should wait for listener to invoke the RecievedMessage.

This method is like this!

    public string RecievedMessage()
    {
        string Recieved ;
        // Some VPN Code  and then return the result;
        return Recieved;
    }

    public string SendAndRecieveMessage(string MessageToSend)
    {
        string RecievedAnswer = string.Empty;

        // Now Sending Message through the VPN
        VpnObject.SendMessage(MessageToSend);

        //Then want to Recieve the answer and return the answer here .

        return RecievedAnswer;
    }

I'm just thinking how can wait for RecievedMessage to invoke then return the result .

You know it is simple to use a variable and assign it value and check for while but it reduced the performance dramatically .

Is there anyway to continue from SendAndRecieveMessage just when RecievedMessage invoked ? (I think it is something with async and await but don't know how!)

Edit :VpnObject is just a sender and receiver through the vpn . it contains a simple socket send and a listener that invoke a method(RecievedMessage) when new message received .

like image 982
Mohammad Sina Karvandi Avatar asked Nov 01 '22 00:11

Mohammad Sina Karvandi


1 Answers

Whether or not you have an alternative to polling depends on whether the library you are using provides any events or callbacks that will tell you when the request has completed.

Either way, the standard approach to exposing the deferred result of an asynchronous operation is to use a Task. Your method signature would look like this:

public Task<string> SendAndRecieveMessage(string MessageToSend)

Now, how you actually implement the method depends on what API VpnObject exposes. TaskCompletionSource is very useful for this kind of thing.

If VpnObject has an event that fires when the request completes:

public Task<string> SendAndReceiveMessage(string messageToSend)
{
    var tcs = new TaskCompletionSource<string>();
    ...
    VpnObject.OnMessageReceived += (s, e) => tcs.SetResult(e.Message);
    ...
    return tcs.Task;
}

If VpnObject can accept a callback that it will invoke when the request completes:

public Task<string> SendAndReceiveMessage(string messageToSend)
{
    var tcs = new TaskCompletionSource<string>();
    ...
    VpnObject.OnMessageReceived(message => tcs.SetResult(message));
    ...
    return tcs.Task;
}

If VpnObject doesn't support any of this, you can fall back to polling:

public async Task<string> SendAndReceiveMessage(string messageToSend)
{
    var tcs = new TaskCompletionSource<string>();
    ...
    while(!VpnObject.IsMessageReceived)
        await Task.Delay(500); // Adjust to a reasonable polling interval
    ...
    return VpnObject.Message;
}
like image 76
Asad Saeeduddin Avatar answered Nov 15 '22 04:11

Asad Saeeduddin