首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >实现线程安全日志记录

实现线程安全日志记录
EN

Stack Overflow用户
提问于 2011-11-15 18:02:51
回答 2查看 4K关注 0票数 5

我的任务是创建一个类,它将围绕几个应用程序收集用户活动。

假设我有一个类TLogging和一个名为Logging的全局对象。

用户活动(屏幕打开等)应该收集在内存中(可能放在TLogging的(字符串)列表中),并在一段时间间隔后(每10分钟)保存到日志文件中,或者在应用程序关闭时。

最重要的是日志必须处于“静默模式”,它不能以任何方式影响用户工作流程:没有屏幕挂起,没有异常。

请告诉我这项任务的方向。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-11-15 18:20:08

这是一个涉及多个领域的非常广泛的问题。以下是一些提示:

  • 至少考虑为此建立一个日志记录框架。较新的Delphi版本附带CodeSiteSmartInspect是另一个使您的类线程安全的alternative.
  • Use同步原语:TMREWSync
  • Make,SmartInspect确保您在尝试编写线程安全的日志记录框架之前了解了多线程和同步所涉及的问题。Martin Harvey的Multithreading - The Delphi Way.
  • Use指南是一个很好的开端,它是一个后台线程,可以定期或在缓冲足够的数据时将日志内容刷新到磁盘。
  • 在这里询问更多具体问题,以便在遇到特定问题时使用。
票数 15
EN

Stack Overflow用户

发布于 2011-11-16 00:10:02

使用OmniThreadLibrary并假设日志记录对象是一个单例对象,这非常简单。我还会限制等待写入的消息的最大数量,这样内部队列就不会使用太多内存。

代码语言:javascript
复制
const
  CMaxMsgCount = 1000;
  CMaxLogTimeout_ms = 10{min}*60{sec/min}*1000{ms/sec};

type
  TLogging = class
  strict private
    FLogMsgCount: IOmniResourceCount;
    FLogQueue: IOmniBlockingCollection;
    FWriter: IOmniTaskControl;
  strict protected
    procedure Logger(const task: IOmniTask);
  public
    constructor Create;
    destructor  Destroy;
    procedure Log(const msg: string);
  end;

var
  Logging: TLogging;

constructor TLogging.Create;
begin
  FLogMsgCount := CreateResourceCount(CMaxMsgCount);
  FLogQueue := TOmniBlockingCollection.Create;
  FWriter := CreateTask(Logger, 'Logger').Run;
end;

destructor TLogging.Destroy;
begin
  FWriter.Terminate;
end;

procedure TLogging.Log(const msg: string);
begin
  FLogQueue.Add(msg);
  FLogMsgCount.Allocate;
end;

procedure TLogging.Logger(const task: IOmniTask);

  procedure Flush;
  var
    logData: TOmniValue;
  begin
    // open file, possibly with retry
    while FLogQueue.TryTake(logData) do begin
      FLogMsgCount.Release;
      // write logData.AsString
    end;
    // close file
  end;

begin
  while DSiWaitForTwoObjects(task.TerminateEvent, FLogMsgCount.Handle, false, CMaxLogTimeout_ms) <> WAIT_OBJECT_0 do
    Flush;
  Flush;
end;

(免责声明:“它在我的机器上编译”,否则未经测试。)

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8134526

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档