如何在继续执行代码之前等待回调方法响应之一?

问题描述 投票:0回答:1

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

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();
}
c# callback steamworks-api
1个回答
0
投票

我假设OnServerRespondedOnServerFailedToRespond是可以修改的功能。您可以使用TaskCompletionSource<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的所有访问。

© www.soinside.com 2019 - 2024. All rights reserved.