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

The callback is not working properly, am I doing it right or is it a library bug/unity issue

提问人:MaltrzD 提问时间:9/7/2023 最后编辑:derHugoMaltrzD 更新时间:9/7/2023 访问量:34

问:

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

服务器返回回调后,方法触发 1 次,一切正常(仅当我们包含UpdateServerInfo()print(info.Hostname);)

但是如果我添加这 2 行:

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

服务器将信息输出到控制台 2 次,第一次是正确的,第二次是正确的,如屏幕截图所示:info.HostnameNull

Console

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

本质上

hostName_Text.text = info.hostname;

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

那是:

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

print 方法只需执行 2 次,仅此而已,没有其他事情发生,代码不会再进一步

C# unity-game-engine 回调

评论


答:

0赞 derHugo 9/7/2023 #1

我能看到的唯一明显的主要问题是,一般来说,大多数 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;
}

评论

0赞 MaltrzD 9/8/2023
谢谢你帮了很多忙