Điều quan trọng là phải hiểu ý nghĩa của "phương pháp đã ném ngoại lệ". Khi một ngoại lệ xảy ra, có một phương pháp cụ thể thực sự thực thi. Chỉ vì tại một số điểm trước khi ngoại lệ, bạn đã gọi phương thức FillCombo()
của riêng mình, điều đó không có nghĩa đó là phương pháp đã ném ngoại lệ. Tuy nhiên,
Tuy nhiên, phương pháp FillCombo()
sẽ nằm trong ngăn xếp ngăn xếp. Đó là lý do tại sao nó rất hữu ích để đăng nhập toàn bộ dấu vết stack. Thật vậy, tôi thường chỉ ghi lại toàn bộ đối tượng Exception
(ví dụ: ex.ToString()
hoặc chỉ chuyển đối tượng ngoại lệ sang string.Format()
hoặc tương tự, sẽ gọi ToString()
cho bạn). Điều này sẽ bao gồm loại ngoại lệ, thông báo, toàn bộ dấu vết ngăn xếp và thậm chí cả thông tin ngoại lệ bên trong nếu có.
Mã bạn nhận được từ câu hỏi khác, cho phương thức GetExecutingMethodName()
, không thực sự là IMHO hữu ích. Bạn sẽ lưu ý rằng điều thực sự là thu thập thông tin theo dấu vết ngăn xếp của vị trí thực thi hiện tại, tìm phương pháp đầu tiên được khai báo trong một loại khác với loại được tuyên bố là GetExecutingMethodName()
.
Đây là sai cho mục đích của bạn vì hai lý do:
- Có vẻ bạn đã tuyên bố rằng phương pháp trong cùng một lớp nơi
Click
xử lý sự kiện của bạn được công bố. Điều này có nghĩa là phương thức xử lý sự kiện bị bỏ qua và vì vậy bạn có được người gọi phương thức đó, là phương thức Control.OnClick()
(tức là phương thức thực sự tăng sự kiện).
Thành thật mà nói, tôi thấy câu trả lời cụ thể là lẻ, vì .NET đã cung cấp API để truy xuất MethodInfo
của phương pháp hiện đang thực hiện: MethodBase.GetCurrentMethod. Và đây là cách đáng tin cậy hơn so với mã Chris Gessler đã viết.
- Có vấn đề hơn, bạn không có cơ hội gọi phương thức này tại thời điểm ngoại lệ được ném! Tốt nhất (tức là ngay cả khi bạn đối phó với câu hỏi về nơi mà phương thức trợ giúp được khai báo), tất cả những gì gọi là sẽ cho bạn biết rằng bạn đang ở phương thức
button1_Click()
của bạn. Nhưng bạn đã biết điều đó, bởi vì mã bạn đang viết để xử lý ngoại lệ là trong phương thức đó.
Nếu bạn muốn biết tên của phương pháp trong phương pháp hiện thực của bạn mà được gọi trước khi ngoại lệ xảy ra, bạn có thể kết hợp hai kỹ thuật: lấy tên của phương pháp hiện đang thực hiện, và sau đó vượt qua với một phương thức lấy cả chuỗi đó và chuỗi dấu vết ngăn xếp từ đối tượng Exception
và để phương thức đó phân tích cú pháp chuỗi dấu vết ngăn xếp để tìm khung ngay trước phương pháp hiện đang thực thi trong theo dõi.
Đó là một chút đau, nhưng có thể thực hiện được. Dưới đây là một ví dụ về những gì mà sẽ trông như thế (đơn giản proof-of-concept chương trình giao diện điều khiển):
static void Main(string[] args)
{
try
{
CallForException();
}
catch (Exception e)
{
Console.WriteLine("Exception occurred calling {0} method", GetCallForExceptionThisMethod(MethodBase.GetCurrentMethod(), e));
}
}
private static string GetCallForExceptionThisMethod(MethodBase methodBase, Exception e)
{
StackTrace trace = new StackTrace(e);
StackFrame previousFrame = null;
foreach (StackFrame frame in trace.GetFrames())
{
if (frame.GetMethod() == methodBase)
{
break;
}
previousFrame = frame;
}
return previousFrame != null ? previousFrame.GetMethod().Name : null;
}
private static void CallForException()
{
DoActualException();
}
private static void DoActualException()
{
throw new NotImplementedException();
}
Cuối cùng, hãy nhớ rằng do phương pháp nội tuyến và tối ưu hóa khác, thậm chí là một vết đống đầy đủ có thể có một số bất thường trong đó, kể cả thậm chí không có tên thật của phương thức mà ngoại lệ được ném ra. Đó là một lý do khác để ghi lại toàn bộ đối tượng Exception
thường hữu ích hơn nhiều; càng có nhiều bối cảnh, bạn càng có khả năng tái tạo lại những gì đã xảy ra.
breakpoint sử dụng để gỡ lỗi mã của bạn và nhìn vào stacktrace – saurabh64
tôi có thể biết trong chế độ Dubug. Nhưng tôi cần phải đăng nhập các lỗi vào một tập tin. Trong môi trường sản xuất, những người sẽ ngồi và Debug !!! @ saurabh64 –
Bạn nên ghi lại toàn bộ dấu vết ngăn xếp. Điều này thường sẽ cung cấp đủ ngữ cảnh để xác định vấn đề. –