我一直在尝试在移动设备上获得在运行时打印堆栈跟踪的可靠方法。我遇到了System.Environment.StackTrace
我正在尝试使用3个班级的东西:
public class Test : MonoBehaviour {
public static void Do() {
Test3.ActionThing(() => {
Test2.DoSomethingElse();
});
}
}
public class Test2 : MonoBehaviour {
void Start () {
Test3.ActionThing(() => {
Debug.Log("Start execution");
Test.Do();
});
}
public static void DoSomethingElse(){
Test3.ActionThing(() => {
var a = 0;
a = int.Parse("s1");
});
}
}
public class Test3 : MonoBehaviour {
public static void ActionThing(Action act){
try{
if (act != null)
act();
}catch(Exception e){
Debug.LogError("Error occured " + e.Message);
Debug.LogError("StackTrace was " + Environment.StackTrace);
}
}
}
当抛出错误时,我得到这个堆栈跟踪
StackTrace was at System.Environment.get_StackTrace() in /Users/builduser/buildslave/mono/build/mcs/class/corlib/System/Environment.cs:line 227
at Test3.ActionThing(System.Action act) in <ProjectPath>\Test3.cs:line 13
at Test2.DoSomethingElse() in <ProjectPath>\Test2.cs:line 14
at Test.<Do>m__0() in <ProjectPath>\Test.cs:line 8
at Test3.ActionThing(System.Action act) in <ProjectPath>\Test3.cs:line 10
at Test.Do() in <ProjectPath>\Test.cs:line 7
at Test2.<Start>m__0() in <ProjectPath>\Test2.cs:line 9
at Test3.ActionThing(System.Action act) in <ProjectPath>\Test3.cs:line 10
at Test2.Start() in <ProjectPath>\Test2.cs:line 7
UnityEngine.Debug:LogError(Object)
Test3:ActionThing(Action) (at Assets/Test3.cs:13)
Test2:DoSomethingElse() (at Assets/Test2.cs:14)
Test:<Do>m__0() (at Assets/Test.cs:8)
Test3:ActionThing(Action) (at Assets/Test3.cs:10)
Test:Do() (at Assets/Test.cs:7)
Test2:<Start>m__0() (at Assets/Test2.cs:9)
Test3:ActionThing(Action) (at Assets/Test3.cs:10)
Test2:Start() (at Assets/Test2.cs:7)
显然,由于我希望在发布版本中将它作为Debug,它不会显示内部堆栈跟踪,只显示消息。
但问题在于堆栈跟踪本身,它甚至会打印方法at Test3.ActionThing(System.Action act) in <ProjectPath>\Test3.cs:line 10
。我想跳过这一点,不要出现在堆栈跟踪中。
任何帮助表示感谢,提前谢谢。如果问题似乎太长,请建议编辑:)
答案 0 :(得分:0)
最直接的方法是简单地处理Environment.StackTrace
字符串并消除你不关心的堆栈帧。
public static void ActionThing(Action act){
try{
if (act != null)
act();
}catch(Exception e){
var relevantStackFrames =
Environment.StackTrace
.Split('\n')
.Skip(2)
.ToArray();
var relevantStackTrace = string.Join("\n", relevantStackFrames);
Debug.LogError("Error occured " + e.Message);
Debug.LogError("StackTrace was " + relevantStackTrace );
}
}
我们分配给relevantStackFrames
的行将堆栈跟踪字符串拆分为一个字符串数组,每个元素都是相应堆栈帧的行。 System.Environment.get_StackTrace()
和Test3.ActionThing(System.Action act)
的堆栈帧是此数组中的前两个元素,由于您不需要它们,我们使用linq的Skip
函数将它们从集合中排除。然后我们将跳过操作的结果转换为带有ToArray
的数组。所以relevantStackFrames
是一个堆栈帧字符串数组,不包括那些你不想要的字符串。
然后我们创建一个名为relevantStackTrace
的字符串,它将包含整个堆栈跟踪的字符串。我们只需加入relevantStackTrace
的每个元素,然后将换行符放回string.Join
。
请务必添加using System.Linq
,以便您可以访问Skip
和ToArray