【问题标题】:System.NullReferenceException Not Being Caught in First Try/Catch BlockSystem.NullReferenceException 未在 First Try/Catch 块中捕获
【发布时间】:2011-05-15 09:13:53
【问题描述】:

我有一个 C# 控制台应用程序,它从“static int Main(string[] args)”开始,创建一个“EventRecievedProcessor”类的实例,然后在该实例上调用一个方法:

static int Main(string[] args)
{
    try
    {
        EventRecievedProcessor proc = new EventRecievedProcessor

        if (!proc.Processs())
        {
            Console.Write(Type + "  processing failed.  Please check logs for more information.");
            Log.Error("Failed to process s");
            return (int)RETURNCODES.INTERNALAPPERROR;
        }
    }
    catch (Exception ex)
    {
        // This is where the System.NullReferenceException from GetLatestEventInfo is currently being caught

        Console.WriteLine("Exception message: " + ex.Message);
        Console.WriteLine("Exception stack trace: " + ex.StackTrace);

        Log.Fatal("An exception has been thrown. Message: " + ex.Message, ex);

        return (int)RETURNCODES.INTERNALAPPERROR;
    }
}

“EventRecievedProcessor”的实例获取记录集合并对其执行 foreach。它为集合中的每条记录在“事件”类上调用一个静态方法 (GetLatestEventInfo):

public class EventRecievedProcessor
{

    public bool Processs()
    { 
        List<Event> events = DAL.GetEvents;

        foreach (Event e in events)
       {
            try
            {
                EventInfo lastEvent = Eventhistory.GetLatestEventInfo(e);
            }
            catch (Exception ex)
            {
                // Log exception and continue processing in foreach loop

                // This is where I want to catch the NullReferenceException from GetLatestEventInfo

                Log.DebugFormat("Error with eventid " + e.EventID);
                Log.Error(ex);
            }
        } 

        return true;
    }
}

调用以下方法时,会抛出 System.NullReferenceException:

public class EventHistory
{

    public static EventInfo GetLatestEventInfo(int customerCode, string premiscode)
    {

        EventInfo info = new EventInfo();

        // Do some work here...
        // This is where the NullReferenceException is being generated.

        return info; 

    }
}

当这里抛出 NullReferenceException 时,我希望 foreach 循环中的 catch 块捕获它,记录它,然后将控制权返回给 foreach 循环以继续处理。相反,异常被顶级“Main”方法捕获,这意味着应用程序中止并且剩余的记录未被处理。

我不知道异常如何/为什么绕过第一个 catch 块。关于我在这里做错了什么有什么想法吗?

添加堆栈跟踪:

System.NullReferenceException:对象引用未设置为对象的实例。 在 C:\Dev\release6.01.100\Events\EventProcessor\EventProcessor\EventHistory.cs:line 65 中的 EventProcessor.EventHistory.GetLatestEventInfo(Event e) 在 C:\Dev\release6.01.100\Events\EventProcessor\EventProcessor\Processors\EventProcessor.cs:line 32 中的 EventProcessor.Processors.EventProcessor.Process() 在 C:\Dev\release6.01.100\Events\EventProcessor\EventProcessor\Program.cs:line 132 中的 EventProcessor.Program.Main(String[] args) 处

对不起,如果我咀嚼了一些名字。这是工作代码,所以我尝试对其进行一些更改以避免任何隐私冲突。

【问题讨论】:

  • 您能否向我们展示显示异常时的堆栈跟踪?
  • 您正在调用 Event.GetLatestEventInfo 静态方法,并向我们展示了 EventHistory.GetLatestEventInfo 的源代码(来自其他类)。这是错字还是应该这样?
  • 您是否验证了对 GetLatestEventInfo 的调用引发了异常(通过查看堆栈跟踪?)。也许 DAL.GetEvents 也会调用 GetlatestEventInfo?
  • 只是为了澄清 - 我可能会通过更改正在使用的对象和方法的名称来混淆这个问题。我草率地未能准确重命名所有内容,也未能更新方法签名。不过从高层来看,堆栈跟踪显示在 EventHistory 中生成的异常(第 65 行),将堆栈冒泡到 EventRecievedProcessor.Processs 的第 32 行的调用代码,最后到第 32 行的顶级调用者132 的 EventProcessor.Main.
  • 您需要向我们展示您的 catch 块中的代码。

标签: c# .net exception-handling try-catch


【解决方案1】:

它不会绕过任何东西。仔细查看您的堆栈跟踪。使用Console.WriteLine(ex.ToString());。您会看到异常并没有从您认为的位置抛出。

【讨论】:

  • 感谢乔恩的反馈。你能稍微扩展一下你的观点吗?堆栈跟踪将 EventHistory.GetLatestEventInfo() 标识为异常源。
  • 异常的来源是 inside of EventHistory.GetLatestEventInfo(),这里没有 try/catch 块。
  • 正确。所以我的期望是异常会冒泡到调用代码,它位于 try/catch 块中?
【解决方案2】:

事实并非如此,这是证据:

class Program
{
    static void Main()
    {
        // no need of try/catch here as exceptions won't propagate to here
        Looper();
    }

    static void Looper()
    {
        int processedRecords = 0;
        for (int i = 0; i < 10; i++)
        {
            try
            {
                Thrower(i);
                processedRecords++;
            }
            catch (NullReferenceException ex)
            { }
        }
        // prints 5 as expected
        Console.WriteLine("processed {0} records", processedRecords);
    }

    static void Thrower(int i)
    {
        if (i % 2 == 0)
        {
            throw new NullReferenceException();
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-11
    • 2014-03-04
    • 1970-01-01
    相关资源
    最近更新 更多