异步追加为.txt在Delphi文件 [英] Asynchronous append to .txt file in delphi

查看:126
本文介绍了异步追加为.txt在Delphi文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图运行一个邮件服务器,我想跟踪喜欢登录事件,连接等等。我想保存在一个日志.txt文件该数据。但因为它有许多工作要做异步我不知道如何锁定文件的当前数据追加,然后松开下次使用。所以基本上我问了一个名为程序说明 asyncAppendToFile(文件名:字符串; textToAppend:字符串)

 程序SMTPServerUserLogin(ASender:TIdSMTPServerContext;
  常量AUsername,APassword:字符串; VAR VAuthenticated:布尔);
开始
  asyncAppendToFile(MYFILE,用户+ AUserName +'试图登录');
结束;


解决方案

从一个应用程序,你可以做一个队列,把线那里。然后,该队列和线程检查写入日志文件中的行中的到达顺序。

  TWorkerThread =类(TThread类)
私人的
  杀:布尔;
  ListLock:TRTLCriticalSection;
  乔布斯:TStringList中;
  JobEvent子:TEvent;
保护
  程序执行;覆盖;
  程序DoJob;
上市
  构造函数创建(CreateSuspended:布尔);
  析构函数销毁;覆盖;
  程序AddJob(S:字符串);
  功能JobCount:整数;
  程序杀;
结束;构造TWorkerThread.Create(CreateSuspended:布尔);
开始
  遗传;
  杀:= FALSE;
  InitializeCriticalSection(ListLock);
  乔布斯:= TStringList.Create;
  JobEvent子:= TEvent.Create(零,真,假,jobs.event');
结束;析构函数TWorkerThread.Destroy;
开始
  Jobs.Free;
  JobEvent.Free;
  DeleteCriticalSection(ListLock);
  遗传;
结束;程序TWorkerThread.Execute;
开始
  而没有被杀死或不Self.Terminated做
    开始
      EnterCriticalSection的(ListLock);
      如果Jobs.Count大于0则
        开始
          LeaveCriticalSection(ListLock);
          DoJob;
        结束
      其他
        开始
          JobEvent.ResetEvent;
          LeaveCriticalSection(ListLock);
          JobEvent.WaitFor(5000);
        结束;
    结束;
结束;程序TWorkerThread.Kill;
开始
  杀:=真;
  JobEvent.SetEvent;
  终止;
结束;程序TWorkerThread.AddJob(S:字符串);
开始
  EnterCriticalSection的(ListLock);
  尝试
    Jobs.Add(多个);
    JobEvent.SetEvent;
  最后
    LeaveCriticalSection(ListLock);
  结束;
结束;程序TWorkerThread.DoJob;
变种F:文本文件;
    小号:字符串;开始
  //选择下一个作业
  EnterCriticalSection的(ListLock);
  尝试
    小号:=作业[0];
  最后
    LeaveCriticalSection(ListLock);
  结束;  //做的工作
  assignfile(F,'server.log的');
  追加(F);
  writeln(F,S);
  closefile(F);  //从队列中删除
  EnterCriticalSection的(ListLock);
  尝试
    Jobs.Delete(0);
  最后
    LeaveCriticalSection(ListLock);
  结束;
结束;

在窗体创建:

 工人:= TWorkerThread.Create(假);
Worker.Priority:= tpLower;

在形态破坏:

  Worker.Kill;
Worker.WaitFor;
Worker.Free;

用法:

 程序SMTPServerUserLogin(ASender:TIdSMTPServerContext;
  常量AUsername,APassword:字符串; VAR VAuthenticated:布尔);
开始
  Worker.AddJob(用户+ AUserName +'试图登录');
结束;

I'm trying to run a mail server and I want to keep track of the events like login, connect etc.. and I want to save this data in a log .txt file. But since it has to be done asynchronously I don't know how to lock the file for the current data append and then release it for next use. So basically I'm asking for help for a procedure called asyncAppendToFile(fileName : String; textToAppend : String)

procedure SMTPServerUserLogin(ASender: TIdSMTPServerContext;
  const AUsername, APassword: String; var VAuthenticated: Boolean);
begin
  asyncAppendToFile(myFile, 'User ' + AUserName + ' attempts a login');  
end; 

解决方案

From one application, you can make a queue and put the lines there. Then a Thread check for this queue and write to the log file the lines in arriving order.

TWorkerThread = class(TThread)
private
  Killed:boolean;
  ListLock:TRTLCriticalSection;
  Jobs:TStringList;
  JobEvent:TEvent;
protected
  procedure Execute; override;
  procedure DoJob;
public
  constructor Create(CreateSuspended: Boolean);
  destructor Destroy; override;
  procedure AddJob(s:string);
  function  JobCount: Integer;
  procedure Kill;
end;

constructor TWorkerThread.Create(CreateSuspended: Boolean);
begin
  inherited;
  Killed:=false;
  InitializeCriticalSection(ListLock);
  Jobs:=TStringList.Create;
  JobEvent:=TEvent.Create(nil, true, false, 'jobs.event');
end;

destructor TWorkerThread.Destroy;
begin
  Jobs.Free;
  JobEvent.Free;
  DeleteCriticalSection(ListLock);
  inherited;
end;

procedure TWorkerThread.Execute;
begin
  while not Killed or not Self.Terminated do
    begin
      EnterCriticalSection(ListLock);
      if Jobs.Count>0 then
        begin
          LeaveCriticalSection(ListLock);
          DoJob;
        end
      else
        begin
          JobEvent.ResetEvent;
          LeaveCriticalSection(ListLock);
          JobEvent.WaitFor(5000);
        end;
    end;
end;

procedure TWorkerThread.Kill;
begin
  Killed:=true;
  JobEvent.SetEvent;
  Terminate;
end;

procedure TWorkerThread.AddJob(s:string);
begin
  EnterCriticalSection(ListLock);
  try
    Jobs.Add(s);
    JobEvent.SetEvent;
  finally
    LeaveCriticalSection(ListLock);
  end;
end;

procedure TWorkerThread.DoJob;
var f:textfile;
    s:string;

begin
  //Pick the next Job
  EnterCriticalSection(ListLock);
  try
    s:=Jobs[0];
  finally
    LeaveCriticalSection(ListLock);
  end;

  //Do the work
  assignfile (f,'server.log');
  append(f);
  writeln(f,s);
  closefile (f);

  //Delete from queue
  EnterCriticalSection(ListLock);
  try
    Jobs.Delete(0);  
  finally
    LeaveCriticalSection(ListLock);
  end;
end;

In Form Create:

Worker:=TWorkerThread.Create(false);
Worker.Priority:=tpLower;

In Form Destroy:

Worker.Kill;
Worker.WaitFor;
Worker.Free;

Usage:

procedure SMTPServerUserLogin(ASender: TIdSMTPServerContext;
  const AUsername, APassword: String; var VAuthenticated: Boolean);
begin
  Worker.AddJob('User ' + AUserName + ' attempts a login');
end; 

这篇关于异步追加为.txt在Delphi文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆