我在重负载下收到此错误消息。这是我的错误日志中的代码摘要和消息。 我尝试了我能想到的一切。任何建议都将不胜感激。
Procedure tCacheInMemory.StreamValue(Name: String; IgnoreCase: Boolean; Var Stream: TStringStream);
Var
i: Integer;
Begin
i := 0;
Try
If Not active Then
exit;
arrayLock.BeginRead;
Try
i := Search(Name);
If i > -1 Then Begin
If fItems[i].value = Nil Then
exit;
fItems[i].value.Position := 0;
Stream.Position := 0;
Stream.CopyFrom(fItems[i].value, fItems[i].value.Size);
End;
Finally
arrayLock.EndRead;
End;
Except { ...execution jumps to here }
On E: Exception Do Begin
x.xLogError('LogErrorCacheInMemory.txt', 'StreamValue:' + E.Message + ' ItemsCount:' + IntToStr( High(fItems)) + 'Memory:' + IntToStr(x.GetMemoryInfoMemory) + endLn + 'StreamSize : ' + IntToStr(fItems[i].value.Size) + ' i=' + IntToStr(i) + 'Name: ' + Name);
Clear;
End
End;
End;
日志条目:
3/10/2011 10:52:59 AM: StreamValue:Stream read error ItemsCount:7562 Memory:240816
StreamSize : 43 i=7506 Name: \\xxxxxxxx\WebRoot\\images\1x1.gif
3/10/2011 12:39:14 PM: StreamValue:Stream read error ItemsCount:10172 Memory:345808
StreamSize : 849 i=10108 Name: \\xxxxxxxx\WebRoot\\css\screen.add.css
3/10/2011 3:45:29 PM: StreamValue:Stream read error ItemsCount:11200 Memory:425464
StreamSize : 3743 i=11198 Name: \\xxxxxxxx\WebRoot\\JS\ArtWeb.js
P.S。
arrayLock: TMultiReadExclusiveWriteSynchronizer;
fItems: Array Of rCache;
Type
rCache = Record
Name: String;
value: TStringStream;
expired: TDateTime;
End;
并且调用函数:
Function tCacheInMemory.CacheCheck(cName: String; Out BlobStream: TStringStream): Boolean;
Begin
Result := False;
If Not IfUseCache Then
exit;
BlobStream.SetSize(0);
BlobStream.Size := 0;
StreamValue(trim(cName), True, BlobStream);
If BlobStream.Size > 0 Then
Result := True;
End;
`
答案 0 :(得分:8)
您没有使用正确的锁定。您正在获取缓存条目数组上的读取锁定,但是一旦找到所需的项目,就可以修改它。首先,您通过分配其Position
属性显式修改它,然后通过读取隐式修改它,修改其Position
属性再次。当其他代码尝试从同一个缓存项读取时,您将受到干扰。如果源流的Position
属性在目标流计算可用字节数和实际请求读取这些字节的时间之间发生变化,则会出现流读取错误。
我有几条与此相关的建议:
TBytes
。 (另外,TStringStream
的使用特别引起了对这些字符串编码是否重要的混淆。简单的文件缓存根本不应该与字符串编码有关。如果必须使用stream,使用与TMemoryStream
类似的内容无关的类。)raise
后致电Clear
。 (当您记录异常时,请确保记录异常的ClassName
值及其消息。)答案 1 :(得分:1)
<击> 外观似乎阻止了你的流文件。
您可以尝试使用Process Monitor查看阻止它的内容。
您可以尝试的另一件事是以read-deny-write模式打开流(请告诉我们您如何打开流)。
这样的事情:
Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite) ;
击> <击> 撞击>
编辑1:忽略部分攻击:您正在使用TStringStream。
我会保留答案,以防万一有人在使用TFileStream时遇到这种错误。
编辑2: Yuriy发布了这个有趣的附录,但我不确定它是否有效,因为BlobStream
未初始化,就像{{3}一样怀疑:
Function TCacheInMemory.CacheCheck(cName: String; Out BlobStream: TStringStream): Boolean;
Begin
Result := False;
Try
If Not IfUseCache Then
exit;
BlobStream.SetSize(0);
BlobStream.Size := 0;
StreamValue(trim(cName), True, BlobStream);
If BlobStream.Size > 0 Then
Result := True;
Except
On E: Exception Do
Begin
x.xLogError('LogErrorCacheInMemory.txt', 'CheckCacheOutStream:' + E.Message + ' ItemsCount:' + IntToStr( High(fItems)) + 'Memory:' + IntToStr(x.GetMemoryInfoMemory));
End;
End;
End;
- 的Jeroen