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

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

修改成:
Lucene.net中的异常处理 public char ReadChar()
        }
在QueryParser\QueryParserTokenManager.cs 中查找ReadChar()方法(有多个):
有一下代码:Lucene.net中的异常处理也许你明白了
  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完工

相关文章:

  • 2021-06-12
  • 2021-07-30
  • 2021-04-22
  • 2021-06-18
  • 2021-12-02
  • 2021-12-20
  • 2021-09-30
猜你喜欢
  • 2022-01-22
  • 2022-02-01
  • 2022-12-23
  • 2021-12-04
  • 2021-05-20
  • 2021-06-08
相关资源
相似解决方案