• Lucene.net中的异常处理


    问题提出:
    最近有人提出在lucene.net中:
    Throwing an exception as a result of a normal situation is extremely bad in .net
    在QueryParser\FastCharStream.cs 中 Refill() 方法里有这么一段:

    int charsRead = input.Read(buffer, newPosition, buffer.Length - newPosition);
    if (charsRead <= 0)
      
    throw new System.IO.IOException("read past eof");
    else
      bufferLength 
    += charsRead;
    问题解决:
    我们知道,在net中捕捉异常是比较耗资源的。
    这里有篇文章对异常做了性能分析和测试:Performance implications of Exceptions in .NET
    初看代码,感觉比较奇怪,为什么要对charsRead做异常处理?是否可以改成这样:
    int charsRead = input.Read(buffer, newPosition, buffer.Length - newPosition);
    if (charsRead > 0)
      bufferLength 
    += charsRead;
    单从代码上看是没有问题的,但放在整个lucene的环境里就有问题。这样会造成死循环。
    为什么会造成死循环?此段异常处理干嘛用的?造成死循环的地方是在ReadChar()方法里(确切的说是调用ReadChar方法的QueryParserTokenManager.cs里)。这里就不分析具体代码了,比较复杂。那我们有没有办法消除这个异常(这个异常是为调用此方法准备的)
    下面先具体看下怎么消除异常:
    QueryParser\FastCharStream.cs 中 Refill() 方法:

    int charsRead = input.Read(buffer, newPosition, buffer.Length - newPosition);
    if (charsRead <= 0)
      
    throw new System.IO.IOException("read past eof");
    else
      bufferLength 
    += charsRead;

    改为:
    int charsRead = input.Read(buffer, newPosition, buffer.Length - newPosition);
    if (charsRead > 0)
      bufferLength 
    += charsRead;
    ReadChar()方法:
     public char ReadChar()
            {
                
    if (bufferPosition >= bufferLength)
                    Refill();
                
    if (bufferPosition < bufferLength)
                    
    return buffer[bufferPosition++];
            }

    修改成:
     public char ReadChar()
            
    {
                
    if (bufferPosition >= bufferLength)
                    Refill();
                
    if (bufferPosition < bufferLength)
                    
    return buffer[bufferPosition++];
                
    else//增加的,为了调用ReadChar()方法消除异常
                    return '\0';
            }
    在QueryParser\QueryParserTokenManager.cs 中查找ReadChar()方法(有多个):
    有一下代码:也许你明白了
      try
       {
           curChar 
    = input_stream.ReadChar();
       }
       
    catch (System.IO.IOException e)
        {
              
    return curPos;
        }
    根据修改的ReadChar()方法可以修改为:
     curChar = input_stream.ReadChar();
      
    if (curChar == '\0')
            
    return curPos;
    可以把try...Catch移除了。

    ok完工
  • 相关阅读:
    没有上司的舞会
    邮票面值设计
    小木棍
    简单的试炼
    区间质数
    加工生产调度
    泥泞的道路
    总数统计
    中庸之道

  • 原文地址:https://www.cnblogs.com/try/p/458983.html
Copyright © 2020-2023  润新知