等待另一个方法调用,然后继续结果

Wait for another method to invoke and then continue with result

我正在尝试从另一个 .dll 文件调用一个方法。 它通过 VPN 发送消息,然后 Return 来自另一台计算机的 RecievedMessage。

正如您现在发送和接收消息需要时间,VpnObject 只需发送消息,我应该等待侦听器调用 RecievedMessage。

这个方法是这样的!

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

我只是在想如何等待 RecievedMessage 调用然后 return 结果。

您知道使用变量并为其赋值并检查 while 很简单,但它会显着降低性能。

在调用 RecievedMessage 时是否可以从 SendAndRecieveMessage 继续? (我认为这是异步和等待的东西,但不知道如何!)

Edit :VpnObject 只是一个通过 vpn 的发送者和接收者。它包含一个简单的套接字发送和一个在收到新消息时调用方法(RecievedMessage)的侦听器。

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

spin while 循环绝对不是实现这个的方法。即使有睡眠,它也很笨重,C# 有多种方法可以解决这个问题。

尚不完全清楚您的 VPN 发送和接收方法是如何工作的,但解决此问题的想法是使用回调方法,或者如您所述,使用 C# 异步框架。

没有关于 VPN 对象的更多详细信息,我只需要一些存根方法。这个想法是创建一个 returns 字符串的任务,将其标记为异步任务,然后 await 让它完成。在您的例子中,任务是接收 VPN 响应字符串。

像这样。

public Task<string> ReceivedMessage()
{
    //get the response from the VPN Object.
    string Received = VpnObject.GetResponse(); 
    var ts = new TaskCompletionSource<string>();
    ts.SetResult(Received);

    // Some VPN Code  and then return the result;
    return ts.Task;
}

public async Task<string> SendAndReceiveMessageAsync(string MessageToSend)
{
    string result = string.Empty;

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

    result = await ReceivedMessage();

    return result;
}

您是否有替代轮询的方法取决于您使用的库是否提供任何事件或回调来告诉您请求何时完成。

无论哪种方式,公开异步操作的延迟结果的标准方法是使用 Task。您的方法签名如下所示:

public Task<string> SendAndRecieveMessage(string MessageToSend)

现在,您如何实际实现该方法取决于 API VpnObject 公开的内容。 TaskCompletionSource对这种东西很有用

如果 VpnObject 有一个事件在请求完成时触发:

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

如果 VpnObject 可以接受请求完成时将调用的回调:

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

如果 VpnObject 不支持其中任何一个,您可以回退到轮询:

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