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

當原生的 (Native) 或 Microsoft Intermediate Language (MSIL) 的位移不明時,定義傳回自 GetNativeOffset()GetILOffset() 方法的值。 這個欄位為常數。

方法

Equals(Object)

判斷指定的物件是否等於目前的物件。

(繼承來源 Object)
GetFileColumnNumber()

取得檔案中的欄位數目,含有正在執行的程式碼。 這項資訊通常擷取自可執行檔的偵錯符號。

GetFileLineNumber()

取得檔案中的行號,含有正在執行的程式碼。 這項資訊通常擷取自可執行檔的偵錯符號。

GetFileName()

取得檔案名稱,含有正在執行的程式碼。 這項資訊通常擷取自可執行檔的偵錯符號。

GetHashCode()

做為預設雜湊函式。

(繼承來源 Object)
GetILOffset()

為正在執行的方法取得從 Microsoft intermediate language (MSIL) 程式碼起始的位移。 這項位移可能是大約值,這是根據 Just-In-Time (JIT) 編譯器是否產生偵錯程式碼而定。 由 DebuggableAttribute 控制產生這個偵錯資訊。

GetMethod()

取得框架正在執行的所在方法。

GetNativeOffset()

為正在執行的方法取得從原生 (Native) Just-In-Time (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

另請參閱