c# - Unity线程错误

查看:188
本文介绍了c# - Unity线程错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

先上代码

 public static void GuestLogin(INClient client ,string USER_ID){
        var message = NAuthenticateMessage.Device(USER_ID);
        client.Login(message, (INSession newSession) =>
        {
            Debug.Log("login success");
            client.Connect(newSession);
            Loading.SetActive(false);
        }, (INError error) =>
        {
            Debug.LogErrorFormat ("Could not login user: '{0}'.", error.Message);
        });
    }

Login 方法(来自第三方插件)

public void Login(INAuthenticateMessage message,
    Action<INSession> callback,
    Action<INError> errback)
{
    authenticate("/user/login", message.Payload, Lang, callback, errback);
}
// login方法里的authenticate方法
private void authenticate(string path,
                                  AuthenticateRequest payload,
                                  string langHeader,
                                  Action<INSession> callback,
                                  Action<INError> errback)
        {
            // Add a collation ID for logs
            payload.CollationId = Guid.NewGuid().ToString();

            var scheme = (SSL) ? "https" : "http";
            var uri = new UriBuilder(scheme, Host, unchecked((int)Port), path).Uri;
            Logger.TraceFormatIf(Trace, "Url={0}, Payload={1}", uri, payload);

            byte[] buffer = Encoding.UTF8.GetBytes(ServerKey + ":");
            var authHeader = String.Concat("Basic ", Convert.ToBase64String(buffer));

            TimeSpan span = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
            transport.Post(uri.ToString(), payload, authHeader, langHeader, Timeout, ConnectTimeout, (data) =>
            {
                AuthenticateResponse authResponse = AuthenticateResponse.Parser.ParseFrom(data);
                Logger.TraceFormatIf(Trace, "DecodedResponse={0}", authResponse);

                switch (authResponse.IdCase)
                {
                    case AuthenticateResponse.IdOneofCase.Session:
                        Logger.Info("authentication");
                        callback(new NSession(authResponse.Session.Token, System.Convert.ToInt64(span.TotalMilliseconds)));
                        break;
                    case AuthenticateResponse.IdOneofCase.Error:
                        errback(new NError(authResponse.Error));
                        break;
                    case AuthenticateResponse.IdOneofCase.None:
                        Logger.Error("Received invalid response from server");
                        break;
                    default:
                        Logger.Error("Received invalid response from server");
                        break;
                }
            }, (e) =>
            {
                errback(new NError(e.Message));
            });
        }

我的问题是,我需要在login成功后设置loading 组件为false,并且跳转到新的场景,但是这时候会报错
SetActive can only be called from the main thread.请大家帮忙看看,小弟感激不尽

解决方案

网络通信方面在另一个线程中,不能在另一个线程操作主线程的东西。
简单方法是,你可以用一个变量中转。例如bool loginFinish=false,登录完成后不调用任何方法,仅仅设置loginFinish=true。
让游戏的主线程每帧都检查loginFinish,一旦看到它变为true,就自己调用Loading.SetActive(false)和其他方法。

复杂点的多线程操作,你可以使用Loom,这东西功能比较全面。

这篇关于c# - Unity线程错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆