Làm cách nào để in Stack Trace hiện tại trong .NET mà không có ngoại lệ?


349

Tôi có mã C # thông thường. Tôi không có ngoại lệ . Tôi muốn lập trình đăng nhập theo dõi ngăn xếp hiện tại cho mục đích gỡ lỗi. Thí dụ:

public void executeMethod() 
{
    logStackTrace();
    method();
}

Câu trả lời:


399

Có một cái nhìn vào System.Diagnosticskhông gian tên. Có rất nhiều goodies trong đó!

System.Diagnostics.StackTrace t = new System.Diagnostics.StackTrace();

Điều này thực sự tốt để có một cú chọc vào để tìm hiểu những gì đang diễn ra dưới mui xe.

Tôi khuyên bạn nên xem xét các giải pháp đăng nhập (chẳng hạn như NLog, log4net hoặc các mẫu và thực hành Thư viện doanh nghiệp của Microsoft) có thể đạt được mục đích của bạn và sau đó là một số. Nguoi ban doi may man!


74
Hãy nhớ rằng đó StackTracecon chó chậm - vì vậy hãy sử dụng nó một cách tiết kiệm.
Jonathan Dickinson

214

Một cách khác System.Diagnostics.StackTracelà sử dụng System.En Môi.StackTrace để trả về một chuỗi đại diện của stacktrace.

Một tùy chọn hữu ích khác là sử dụng các biến$CALLER$CALLSTACK gỡ lỗi trong Visual Studio vì điều này có thể được kích hoạt trong thời gian chạy mà không cần xây dựng lại ứng dụng.


6
Environment.StackTracechỉ là một ví dụ mới StackTrace.
Daniel

9
@Daniel: Có, nhưng System.Environment.StackTracecó thể là một cách thuận tiện hơn để truy cập thông tin đó.
larsmoa

6
@AndreiRinea: Trên thực tế, tôi tin rằng bạn có thể truy cập số dòng bằng cách sử dụng System.Diagnostics.StackTrace- xem msdn.microsoft.com/en-us/l
Library / trộm

5
Nó không gây phiền nhiễu mà Environment.StackTraceluôn luôn bắt đầu với at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo) at System.Environment.get_StackTrace()? Đó không phải là một phần của dấu vết ngăn xếp hiện tại như tại thời điểm mà ai đó đang tìm kiếm nó.
Rory

7
@Rory, hãy xem công cụ xây dựng StackTrace (int SkipFrames, bool fNeedFileInfo), bạn có thể bỏ qua khung bắt đầu. ipen phương thức trong ILSpy và bạn có thể thấy những gì nó làm
Walter Vehoeven

39

Có hai cách để làm điều này. Các System.Diagnostics.StackTrace()sẽ cung cấp cho bạn một stack trace cho thread hiện hành. Nếu bạn có một tham chiếu đến một Threadthể hiện, bạn có thể lấy dấu vết ngăn xếp cho điều đó thông qua phiên bản quá tải của StackTrace().

Bạn cũng có thể muốn kiểm tra câu hỏi Stack Overflow Làm thế nào để có được stacktrace của luồng không hiện tại? .


16

Bạn cũng có thể làm điều này trong trình gỡ lỗi Visual Studio mà không cần sửa đổi mã.

  1. Tạo một điểm dừng nơi bạn muốn xem dấu vết ngăn xếp.
  2. Nhấp chuột phải vào điểm dừng và chọn "Hành động ..." trong VS2015. Trong VS2010, chọn "Khi nhấn ...", sau đó bật "In tin nhắn".
  3. Đảm bảo "Tiếp tục thực hiện" được chọn.
  4. Nhập một số văn bản bạn muốn in ra.
  5. Thêm $ CALLSTACK bất cứ nơi nào bạn muốn để xem dấu vết ngăn xếp.
  6. Chạy chương trình trong trình gỡ lỗi.

Tất nhiên, điều này không hữu ích nếu bạn đang chạy mã trên một máy khác, nhưng nó khá tiện dụng để có thể tự động nhổ dấu vết ngăn xếp mà không ảnh hưởng đến mã phát hành hoặc thậm chí không cần phải khởi động lại chương trình.


7
Nếu bạn muốn xem dấu vết ngăn xếp và bạn đã ở trong trình gỡ lỗi VS ở điểm dừng, chỉ cần truy cập Debug-> Windows-> Call Stack.
khargoosh

5
Có, nhưng nếu bạn làm theo cách này, chương trình không phải dừng lại để bạn xem dấu vết ngăn xếp.
Hank Schultz

7
Console.WriteLine(
    new System.Diagnostics.StackTrace().ToString()
    );

Đầu ra sẽ tương tự như:

tại YourNamespace.Program.executeMethod (Thông báo chuỗi)

tại YourNamespace.Program.Main (String [] args)

Thay thế Console.WriteLinebằng Logphương pháp của bạn . Trên thực tế, không cần cho .ToString()trường hợp Console.WriteLine vì nó chấp nhận object. Nhưng bạn có thể cần điều đó cho phương thức Log (chuỗi thông điệp) của bạn.


-2
   private void ExceptionTest()
    {
        try
        {
            int j = 0;
            int i = 5;
            i = 1 / j;
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error: " + ex.Message);
            var stList = ex.StackTrace.ToString().Split('\\');
            Console.WriteLine("Exception occurred at " + stList[stList.Count() - 1]);
        }
    }

Dường như làm việc cho tôi


3
Đây chỉ là một ngoại lệ rõ ràng. Tại sao? Tại sao không chỉ đơn giản là khởi tạo một ngoại lệ, chứ không phải là một lỗ hổng sẽ tạo ra một ngoại lệ trong chính nó? Lợi ích của logic bắt bổ sung cần có để có được ngoại lệ thực tế là gì? Và ngay cả khi đó, bạn vẫn bỏ qua câu hỏi được đăng thực tế về cách lấy dấu vết ngăn xếp mà không có ngoại lệ (đọc tiêu đề).
Flater

đó là một câu trả lời hợp lệ, nhưng là một giải pháp tuyệt vời. KHÔNG ai nên sử dụng nó ... @Jeff bất cứ nơi nào bạn làm điều đó, thay thế nó bằng một mã gốc như các câu trả lời khác được đề xuất.
Tomer W
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.