c# – Unity3D有什么好的全局异常处理策略?

前端之家收集整理的这篇文章主要介绍了c# – Unity3D有什么好的全局异常处理策略?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在考虑做一些Unity3D脚本的东西,我想设置全局异常处理系统.这不是在游戏的发布版本中运行,其目的是捕获用户脚本中的异常以及编辑器脚本中的异常,并确保将其转发到数据库进行分析(也可以向相关的开发人员发送电子邮件,以便他们可以解决他们的嘶嘶声).

在一个香草C#应用程序,我将有一个try-catch在Main方法.在WPF中我会挂钩一个或多个unhandled exception events.在Unity …?

到目前为止,我能够想到的最好的是这样的:

using UnityEngine;
using System.Collections;

public abstract class BehavIoUrBase : MonoBehavIoUr {

    // Use this for initialization
    void Start () {

    }

    // Update is called once per frame
    void Update () {
        try
        {
            performUpdate();
            print("hello");
        }
        catch (System.Exception e)
        {
            print(e.ToString());
        }

    }

    public abstract void performUpdate();

}

在其他脚本中,我派生BehavIoUrBase而不是MonoBehavior,并执行performUpdate()而不是Update().我没有为Editor clases实现并行版本,但我认为我必须在这里做同样的事情.

不过,我不喜欢这个策略,因为我必须把它运送到我们从社区获取的任何脚本(我必须在团队中执行).编辑器脚本没有单个入口与MonoBehavior相当,所以我认为我必须实现异常安全版本的向导,编辑器等等.

我已经看到关于使用Application.RegisterLogCallback捕获日志消息(而不是例外)的建议,但这让我不舒服,因为我需要解析调试日志字符串,而不是访问实际的异常和堆栈跟踪.

那么什么是正确的事情呢?

解决方法

我在这里找到了RegisterLogCallback的一个工作实现: http://answers.unity3d.com/questions/47659/callback-for-unhandled-exceptions.html

在我自己的实现中,我使用它来调用自己的MessageBox.Show而不是写入日志文件.我刚从每个场景调用SetupExceptionHandling.

static bool isExceptionHandlingSetup;
    public static void SetupExceptionHandling()
    {
        if (!isExceptionHandlingSetup)
        {
            isExceptionHandlingSetup = true;
            Application.RegisterLogCallback(HandleException);
        }
    }

    static void HandleException(string condition,string stackTrace,LogType type)
    {
        if (type == LogType.Exception)
        {
            MessageBox.Show(condition + "\n" + stackTrace);
        }
    }

我现在也有错误处理程序通过这个例程发送给我,所以我总是知道我的应用程序崩溃,尽可能多的细节.

internal static void ReportCrash(string message,string stack)
    {
        //Debug.Log("Report Crash");
        var errorMessage = new StringBuilder();

        errorMessage.AppendLine("FreeCell Quest " + Application.platform);

        errorMessage.AppendLine();
        errorMessage.AppendLine(message);
        errorMessage.AppendLine(stack);

        //if (exception.InnerException != null) {
        //    errorMessage.Append("\n\n ***INNER EXCEPTION*** \n");
        //    errorMessage.Append(exception.InnerException.ToString());
        //}

        errorMessage.AppendFormat
        (
            "{0} {1} {2} {3}\n{4},{5},{6},{7}x {8}\n{9}x{10} {11}dpi FullScreen {12},{13},{14} vmem: {15} Fill: {16} Max Texture: {17}\n\nScene {18},Unity Version {19},Ads Disabled {18}",SystemInfo.deviceModel,SystemInfo.deviceName,SystemInfo.deviceType,SystemInfo.deviceUniqueIdentifier,SystemInfo.operatingSystem,Localization.language,SystemInfo.systemMemorySize,SystemInfo.processorCount,SystemInfo.processorType,Screen.currentResolution.width,Screen.currentResolution.height,Screen.dpi,Screen.fullScreen,SystemInfo.graphicsDeviceName,SystemInfo.graphicsDeviceVendor,SystemInfo.graphicsMemorySize,SystemInfo.graphicsPixelFillrate,SystemInfo.maxTextureSize,Application.loadedLevelName,Application.unityVersion,GameSettings.AdsDisabled
        );

        //if (Main.Player != null) {
        //    errorMessage.Append("\n\n ***PLAYER*** \n");
        //    errorMessage.Append(XamlServices.Save(Main.Player));
        //}

        try {
            using (var client = new WebClient()) {
                var arguments = new NameValueCollection();
                //if (loginResult != null)
                //    arguments.Add("SessionId",loginResult.SessionId.ToString());
                arguments.Add("report",errorMessage.ToString());
                var result = Encoding.ASCII.GetString(client.UploadValues(serviceAddress + "/ReportCrash",arguments));
                //Debug.Log(result);
            }
        } catch (WebException e) {
            Debug.Log("Report Crash: " + e.ToString());
        }
    }

猜你在找的C#相关文章