【发布时间】:2011-03-15 21:34:19
【问题描述】:
我在负载过重的情况下收到此错误消息。这是我的错误日志中的代码摘要和消息。 我尝试了我能想到的一切。任何建议将不胜感激。
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
附:
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;
`
【问题讨论】:
-
您确定创建了“Stream”吗?我没有看到任何代码检查。您为 Items[].Value 执行此操作。 Search() 还有什么作用?它是否与流交互?
-
您标记了执行跳转的位置到 - 它从哪里跳转从到达那里?
-
流已创建。您可以在错误日志中看到 StreamSize 和大小(以字节为单位)。 Items.Value 是一个 TStringStream。搜索是一种自定义的二分搜索。它不交互。只返回索引。
-
StreamSize 在您的日志中指的是 Items[].value 而不是 Stream 变量。您的代码中有多个流变量。
-
与错误无关的代码有两点:(1)您不应将
Stream参数作为var传递。按值传递它,并将其声明的类型更改为TStream,允许调用者传递任何类型的流而不是完全TStringStream对象。 (2) 如果您在缓存中找到的流比目标流的当前内容短,那么目标流最后会包含垃圾。复制后需要截断。
标签: delphi delphi-2010