0

我目前正在开发一个系统,该系统可以主动跟踪服务器信息。对于一些方法,我需要它是异步的,但是,有一些以同步方式(外部库)实现。我有这个代码:

m_ServerQuery = HServerQuery.Invalid;

m_PingResponse = new ISteamMatchmakingPingResponse(OnServerResponded, OnServerFailedToRespond);
try
{
    m_ServerQuery = SteamMatchmakingServers.PingServer((uint)ip, port, m_PingResponse);
    await Task.Delay(500);
    SteamMatchmakingServers.CancelServerQuery(m_ServerQuery);
}
    catch
{
    Console.WriteLine($"*** Something went wrong while pinging server ***");
}

从上面的代码片段可以看出,PingResponse 类继承了两个方法,当从 Steam 发送响应时,它们充当“回调”。现在等待它 0.5 毫秒是可行的,但是,我认为最好实现它以等待这两种方法之一触发: OnServerResponded, OnServerFailedToRespond 我将如何实现这一目标?ISteamMatchmakingPingResponse定义:

public class ISteamMatchmakingPingResponse
{
    public ISteamMatchmakingPingResponse(ServerResponded onServerResponded, ServerFailedToRespond onServerFailedToRespond);

    ~ISteamMatchmakingPingResponse();

    public static explicit operator IntPtr(ISteamMatchmakingPingResponse that);

    public delegate void ServerResponded(gameserveritem_t server);
    public delegate void ServerFailedToRespond();
}
4

1 回答 1

0

我假设OnServerRespondedOnServerFailedToRespond是您可以修改的功能。您可以使用 aTaskCompletionSource<bool>并等待它的任务。像这样的东西。

TaskCompletionSource<bool> pingSucceed;

//Not sure about the firm of your callback functions, just a void function for this example
void OnServerResponded()
{
    //Do any task you need to do
    //..

    if(pingSucceed != null)
        pingSucceed.TrySetResult(true);
}

void OnServerFailedToRespond()
{
    //Do any task you need to do
    //..

    if(pingSucceed != null)
        pingSucceed.TrySetResult(false);
}

//Now the call
async Task TheFunctionThatPingsTheServer()
{
    //Do any task you need to do prior to the ping
    //..

    pingSucceed = new TaskCompletionSource<bool>();
    m_ServerQuery = SteamMatchmakingServers.PingServer((uint)ip, port, m_PingResponse);
    var succeed = await pingSucceed.Task;
    pingSucceed.Dispose();
    pingSucceed = null;

    //Here succeed will be true if server answered, else false.

}

请注意这一点,如果OnServerResponded和/或OnServerFailedToRespond在不同的线程中运行,那么您必须pingSucceed通过锁定对象来保护所有访问以避免竞争条件。

于 2020-06-17T01:55:32.760 回答