我目前正在使用一个主动跟踪服务器信息的系统。对于一些方法,我需要它是异步的,但是,有一些是以同步方式实现的(外部库)。我有此代码:
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();
}
我假设OnServerResponded
和OnServerFailedToRespond
是可以修改的功能。您可以使用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
的所有访问。