StackFrame 类

定义

提供关于 StackFrame(表示当前线程的调用堆栈中的一个函数调用)的信息。

C#
public sealed class StackFrame
C#
public class StackFrame
C#
[System.Serializable]
public class StackFrame
C#
[System.Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public class StackFrame
继承
StackFrame
属性

示例

以下示例演示如何使用 StackFrame 类为堆栈跟踪提供堆栈帧信息。

C#
using System;
using System.Diagnostics;

namespace StackFrameExample
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Method1();
            }
            catch (Exception e)
            {
                StackTrace st = new StackTrace();
                StackTrace st1 = new StackTrace(new StackFrame(true));
                Console.WriteLine(" Stack trace for Main: {0}",
                   st1.ToString());
                Console.WriteLine(st.ToString());
            }
            Console.WriteLine("Press Enter to exit.");
            Console.ReadLine();
        }
        private static void Method1()
        {
            try
            {
                Method2(4);
            }
            catch (Exception e)
            {
                StackTrace st = new StackTrace();
                StackTrace st1 = new StackTrace(new StackFrame(true));
                Console.WriteLine(" Stack trace for Method1: {0}",
                   st1.ToString());
                Console.WriteLine(st.ToString());
                // Build a stack trace for the next frame.
                StackTrace st2 = new StackTrace(new StackFrame(1, true));
                Console.WriteLine(" Stack trace for next level frame: {0}",
                   st2.ToString());
                throw e;
            }
        }
        private static void Method2( int count)
        {
            try
            {
                if (count < 5)
                    throw new ArgumentException("count too large", "count");
            }
            catch (Exception e)
            {
                StackTrace st = new StackTrace();
                StackTrace st1 = new StackTrace(new StackFrame(2,true));
                Console.WriteLine(" Stack trace for Method2: {0}",
                   st1.ToString());
                Console.WriteLine(st.ToString());
                throw e;
            }
        }
    }
}

以下示例演示如何使用 类的成员 StackFrame

C#

using System;
using System.Diagnostics;

using SampleInternal;

namespace SamplePublic
{
    // This console application illustrates various uses
    // of the StackTrace and StackFrame classes.
    class ConsoleApp
    {
       [STAThread]
       static void Main()
        {
            ClassLevel1 mainClass = new ClassLevel1();

            try {
                mainClass.InternalMethod();
            }
            catch (Exception) {
               Console.WriteLine(" Main method exception handler");

               // Display file and line information, if available.
               StackTrace st = new StackTrace(new StackFrame(true));
               Console.WriteLine(" Stack trace for current level: {0}",
                   st.ToString());
               Console.WriteLine(" File: {0}",
                  st.GetFrame(0).GetFileName());
               Console.WriteLine(" Line Number: {0}",
                   st.GetFrame(0).GetFileLineNumber().ToString());

               Console.WriteLine();
               Console.WriteLine("-------------------------------------------------\n");
            }
        }
    }
}

namespace SampleInternal
{
   public class ClassLevel1
   {
      public void InternalMethod()
      {
         try
         {
            ClassLevel2 nestedClass = new ClassLevel2();
            nestedClass.Level2Method();
         }
         catch (Exception e)
         {
            Console.WriteLine(" InternalMethod exception handler");

            // Build a stack trace from one frame, skipping the
            // current frame and using the next frame.  By
            // default, file and line information are not displayed.
            StackTrace st = new StackTrace(new StackFrame(1));
            Console.WriteLine(" Stack trace for next level frame: {0}",
               st.ToString());
            Console.WriteLine(" Stack frame for next level: ");
            Console.WriteLine("   {0}", st.GetFrame(0).ToString());

            Console.WriteLine(" Line Number: {0}",
               st.GetFrame(0).GetFileLineNumber().ToString());

            Console.WriteLine();
            Console.WriteLine("   ... throwing exception to next level ...");
            Console.WriteLine("-------------------------------------------------\n");
            throw e;
         }
      }
   }

   public class ClassLevel2
   {
      public void Level2Method()
      {
         try
         {
            ClassLevel3 nestedClass = new ClassLevel3();
            nestedClass.Level3Method();
         }
         catch (Exception e)
         {
            Console.WriteLine(" Level2Method exception handler");

            // Display the full call stack at this level.
            StackTrace st1 = new StackTrace(true);
            Console.WriteLine(" Stack trace for this level: {0}",
               st1.ToString());

            // Build a stack trace from one frame, skipping the current
            // frame and using the next frame.
            StackTrace st2 = new StackTrace(new StackFrame(1, true));
            Console.WriteLine(" Stack trace built with next level frame: {0}",
               st2.ToString());

            // Build a stack trace skipping the current frame, and
            // including all the other frames.
            StackTrace st3 = new StackTrace(1, true);
            Console.WriteLine(" Stack trace built from the next level up: {0}",
               st3.ToString());

            Console.WriteLine();
            Console.WriteLine("   ... throwing exception to next level ...");
            Console.WriteLine("-------------------------------------------------\n");
            throw e;
         }
      }
   }

   public class ClassLevel3
   {
      public void Level3Method()
      {
         try
         {
            ClassLevel4 nestedClass = new ClassLevel4();
            nestedClass.Level4Method();
         }
         catch (Exception e)
         {
            Console.WriteLine(" Level3Method exception handler");

            // Build a stack trace from a dummy stack frame.
            // Explicitly specify the source file name and
            // line number.
            StackTrace st = new StackTrace(new StackFrame("source.cs", 60));
            Console.WriteLine(" Stack trace with dummy stack frame: {0}",
                        st.ToString());
            for(int i =0; i< st.FrameCount; i++ )
            {
               // Display the stack frame properties.
               StackFrame sf = st.GetFrame(i);
               Console.WriteLine(" File: {0}", sf.GetFileName());
               Console.WriteLine(" Line Number: {0}",
                  sf.GetFileLineNumber());
               // Note that the column number defaults to zero
               // when not initialized.
               Console.WriteLine(" Column Number: {0}",
                  sf.GetFileColumnNumber());
               if (sf.GetILOffset() != StackFrame.OFFSET_UNKNOWN)
               {
                  Console.WriteLine(" Intermediate Language Offset: {0}",
                     sf.GetILOffset());
               }
               if (sf.GetNativeOffset() != StackFrame.OFFSET_UNKNOWN)
               {
                  Console.WriteLine(" Native Offset: {0}",
                     sf.GetNativeOffset());
               }
            }
            Console.WriteLine();
            Console.WriteLine("   ... throwing exception to next level ...");
            Console.WriteLine("-------------------------------------------------\n");
            throw e;
         }
      }
   }

   public class ClassLevel4
   {
      public void Level4Method()
      {
         try
         {
            ClassLevel5 nestedClass = new ClassLevel5();
            nestedClass.Level5Method();
         }
         catch (Exception e)
         {
            Console.WriteLine(" Level4Method exception handler");

            // Build a stack trace from a dummy stack frame.
            // Explicitly specify the source file name, line number
            // and column number.
            StackTrace st = new StackTrace(new StackFrame("source.cs", 79, 24));
            Console.WriteLine(" Stack trace with dummy stack frame: {0}",
                           st.ToString());

            // Access the StackFrames explicitly to display the file
            // name, line number and column number properties.
            // StackTrace.ToString only includes the method name.
            for(int i =0; i< st.FrameCount; i++ )
            {
               StackFrame sf = st.GetFrame(i);
               Console.WriteLine(" File: {0}", sf.GetFileName());
               Console.WriteLine(" Line Number: {0}",
                  sf.GetFileLineNumber());
               Console.WriteLine(" Column Number: {0}",
                  sf.GetFileColumnNumber());
            }
            Console.WriteLine();
            Console.WriteLine("   ... throwing exception to next level ...");
            Console.WriteLine("-------------------------------------------------\n");
            throw e;
         }
      }
   }

   public class ClassLevel5
   {
      public void Level5Method()
      {
         try
         {
            ClassLevel6 nestedClass = new ClassLevel6();
            nestedClass.Level6Method();
         }
         catch (Exception e)
         {
            Console.WriteLine(" Level5Method exception handler");

            StackTrace st = new StackTrace();

            // Display the most recent function call.
            StackFrame sf = st.GetFrame(0);
            Console.WriteLine();
            Console.WriteLine("  Exception in method: ");
            Console.WriteLine("      {0}", sf.GetMethod());

            if (st.FrameCount >1)
            {
               // Display the highest-level function call
               // in the trace.
               sf = st.GetFrame(st.FrameCount-1);
               Console.WriteLine("  Original function call at top of call stack):");
               Console.WriteLine("      {0}", sf.GetMethod());
            }

            Console.WriteLine();
            Console.WriteLine("   ... throwing exception to next level ...");
            Console.WriteLine("-------------------------------------------------\n");
            throw e;
         }
      }
   }

   public class ClassLevel6
   {
      public void Level6Method()
      {
         throw new Exception("An error occurred in the lowest internal class method.");
      }
   }
}

注解

StackFrame在执行线程期间,在调用堆栈上创建并推送每个函数调用。 堆栈帧始终包含 MethodBase 信息,还可以选择包含文件名、行号和列号信息。

StackFrame 有关调试生成配置的信息最为丰富。 默认情况下,调试版本包含调试符号,而发布版本不包含。 调试符号包含用于构造 StackFrame 对象的大部分文件、方法名称、行号和列信息。

构造函数

StackFrame()

初始化 StackFrame 类的新实例。

StackFrame(Boolean)

初始化 StackFrame 类的新实例,可以选择捕获源信息。

StackFrame(Int32)

初始化与当前堆栈帧之上的帧对应的 StackFrame 类的新实例。

StackFrame(Int32, Boolean)

初始化与当前堆栈帧之上的帧对应的 StackFrame 类的新实例,可以选择捕获源信息。

StackFrame(String, Int32)

初始化只包含给定文件名和行号的 StackFrame 类的新实例。

StackFrame(String, Int32, Int32)

初始化只包含给定文件名、行号和列号的 StackFrame 类的新实例。

字段

OFFSET_UNKNOWN

定义当本机或 Microsoft 中间语言 (Microsoft Intermediate Language, MSIL) 偏移量未知时从 GetNativeOffset()GetILOffset() 方法返回的值。 此字段为常数。

方法

Equals(Object)

确定指定对象是否等于当前对象。

(继承自 Object)
GetFileColumnNumber()

获取文件中包含所执行代码的列号。 该信息通常从可执行文件的调试符号中提取。

GetFileLineNumber()

获取文件中包含所执行代码的行号。 该信息通常从可执行文件的调试符号中提取。

GetFileName()

获取包含所执行代码的文件名。 该信息通常从可执行文件的调试符号中提取。

GetHashCode()

作为默认哈希函数。

(继承自 Object)
GetILOffset()

获取离开所执行方法的 Microsoft 中间语言 (Microsoft Intermediate Language, MSIL) 代码开头的偏移量。 根据实时 (JIT) 编译器是否正在生成调试代码,此偏移量可能是近似量。 该调试信息的生成受 DebuggableAttribute 控制。

GetMethod()

获取在其中执行帧的方法。

GetNativeOffset()

获取相对于所执行方法的本机实时 (JIT) 编译代码开头的偏移量。 该调试信息的生成受 DebuggableAttribute 类控制。

GetType()

获取当前实例的 Type

(继承自 Object)
MemberwiseClone()

创建当前 Object 的浅表副本。

(继承自 Object)
ToString()

生成堆栈跟踪的可读表示形式。

扩展方法

GetNativeImageBase(StackFrame)

返回一个指针,该指针指向此堆栈帧正在执行的本机映像的基址。

GetNativeIP(StackFrame)

获取一个接口指针,该指针指向正在执行的方法的本机代码起始位置。

HasILOffset(StackFrame)

指示离开正在执行的方法的 IL 代码开头的偏移量是否可用。

HasMethod(StackFrame)

指示有关在其中执行指定帧的方法的信息是否可用。

HasNativeImage(StackFrame)

指示本机映像是否适用于指定的堆栈帧。

HasSource(StackFrame)

指示包含指定堆栈帧正在执行的代码的文件是否可用。

适用于

产品 版本
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 2.0, 2.1
UWP 10.0

另请参阅