回调无法正常工作,我做得对吗还是库错误/统一问题

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

我对 RustRcon 库有疑问

private void Update()
{
    timer += Time.deltaTime;

    if(timer >= updateTime && connectionChecker.Status)
    {
        try
        {
            rconManager.Client.SendCommand(new GetServerInfo((info) => {
                UpdateServerInfo(info);
            }));
        }
        catch(Exception ex)
        {
            print(ex.Message);
        }

        timer = 0;
    }
}

private void UpdateServerInfo(RustRcon.Types.Response.ServerInfo info)
{
    print(info.Hostname);
    hostName_Text.text = info.Hostname;
}

服务器返回回调后,方法

UpdateServerInfo()
触发1次,一切正常(仅当我们包含
print(info.Hostname);
时)

但是如果我将这两行添加到其中:

    print(info.Hostname);
    hostName_Text.text = info.hostname;

服务器向控制台输出信息2次,第一次正确

info.Hostname
,第二次
Null
如截图所示:

Console

可能是什么问题或者我做错了什么

本质上

hostName_Text.text = info.hostname;

应该填充舞台上的文本,但这不会发生,因为 print 执行了 2 次,然后代码就结束了

即:

    print(info.Hostname);
    hostName_Text.text = info.hostname;

print 方法只是执行了 2 次,就这样,没有发生任何其他事情,代码不再继续执行

c# unity-game-engine callback
1个回答
0
投票

我能看到的唯一明显的主要问题是,一般来说,大多数 Unity API 不是线程保存的,只能在 Unity 主线程上使用 -> 你的异步服务器回调方法可能会在不同的线程上调用

你可以尝试例如

// use a thread-safe stack
// stack because you only want to display the latest received
private static readonly ConcurrentStack<Action> actions = new ();

private void Update()
{
    // handle received actions on the Unity main thread
    if(action.TryPop(out var action))
    {
        action?.Invoke();

        actions.Clear();
    }

    timer += Time.deltaTime;

    if(timer >= updateTime && connectionChecker.Status)
    {
        try
        {
            rconManager.Client.SendCommand(new GetServerInfo((info) => 
            {
                // instead of directly executiing the callback rather schedule it for the next Update call on the Unity main thread
                actions.Enqueue(()=> UpdateServerInfo(info));
            }));
        }
        catch(Exception ex)
        {
            print(ex.Message);
        }

        timer = 0;
    }
}

private void UpdateServerInfo(RustRcon.Types.Response.ServerInfo info)
{
    print(info.Hostname);
    hostName_Text.text = info.Hostname;
}
© www.soinside.com 2019 - 2024. All rights reserved.