我做了一个简单的多线程程序,主要是有多个任务,实现无间断定时把任务中定的一个目录里的内容复制到另一个目录。我将目录的程序作成一个单独的函数,现在遇到的问题是:如果有两个任务同时在执行线程,则不能将目录里的内容复制到另一个目录里。关键代码如下:
// UTrdBatchMove unit
procedure TrdBatchMove.Execute;
begin
while true do
begin
FrmMain.LogBusyOrIdle(iTrdIndex, iTimes, 1, strMName);
CopyDir;
Inc(iTimes);
FrmMain.LogBusyOrIdle(iTrdIndex, iTimes, 0, strMName);
Sleep(iPause * 1000 * 60); // 1 sec
end;
end;procedure TrdBatchMove.CopyDir();
var
d: TDate;
arr: array[1..7] of string;
i: integer;
begin
if Length(strFromDir) <= 0 then
exit;
if DirectoryExists(strToDir) then
begin
DoCopyDir(strFromDir, strToDir, bIncSubDir);
end else
FrmMain.LogBusyOrIdle(iTrdIndex, 0, -2, strMName);
end;// 复制函数的unit
function DoCopyDir(sDirName: string; sToDirName: string;
IncSubDir : Boolean = true): Boolean;
var
hFindFile: Cardinal;
t, tfile: string;
FindFileData: WIN32_FIND_DATA;
begin
if DirectoryExists(sDirName) then
begin
try
ChDir(sDirName);
ForceDirectories(sToDirName);
hFindFile := FindFirstFile('*.*', FindFileData);
if hFindFile <> INVALID_HANDLE_VALUE then
begin
repeat
tfile := FindFileData.cFileName;
if (tfile = '.') or (tfile = '..') then
Continue;
if (FindFileData.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY) and
IncSubDir then
begin
t := sToDirName + '\' + tfile;
if not DirectoryExists(t) then
ForceDirectories(t);
if sDirName[Length(sDirName)] <> '\' then
DoCopyDir(sDirName + '\' + tfile, t)
else
DoCopyDir(sDirName + tfile, sToDirName + tfile);
end
else
begin
t := sToDirName + '\' + tFile;
CopyFile(PChar(tfile), PChar(t), false);
FrmMain.LogStatus(t);
end;
until FindNextFile(hFindFile, FindFileData) = false;
FindClose(hFindFile);
end
else
begin
FrmMain.LogBusyOrIdle(0, 0, -1, 'invl :' + sToDirName);
result := false;
exit;
end;
ChDir('d:');
except on e: Exception do
FrmMain.LogBusyOrIdle(0, 0, -1, e.Message);
end;
end;
result := true;
end;
// UTrdBatchMove unit
procedure TrdBatchMove.Execute;
begin
while true do
begin
FrmMain.LogBusyOrIdle(iTrdIndex, iTimes, 1, strMName);
CopyDir;
Inc(iTimes);
FrmMain.LogBusyOrIdle(iTrdIndex, iTimes, 0, strMName);
Sleep(iPause * 1000 * 60); // 1 sec
end;
end;procedure TrdBatchMove.CopyDir();
var
d: TDate;
arr: array[1..7] of string;
i: integer;
begin
if Length(strFromDir) <= 0 then
exit;
if DirectoryExists(strToDir) then
begin
DoCopyDir(strFromDir, strToDir, bIncSubDir);
end else
FrmMain.LogBusyOrIdle(iTrdIndex, 0, -2, strMName);
end;// 复制函数的unit
function DoCopyDir(sDirName: string; sToDirName: string;
IncSubDir : Boolean = true): Boolean;
var
hFindFile: Cardinal;
t, tfile: string;
FindFileData: WIN32_FIND_DATA;
begin
if DirectoryExists(sDirName) then
begin
try
ChDir(sDirName);
ForceDirectories(sToDirName);
hFindFile := FindFirstFile('*.*', FindFileData);
if hFindFile <> INVALID_HANDLE_VALUE then
begin
repeat
tfile := FindFileData.cFileName;
if (tfile = '.') or (tfile = '..') then
Continue;
if (FindFileData.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY) and
IncSubDir then
begin
t := sToDirName + '\' + tfile;
if not DirectoryExists(t) then
ForceDirectories(t);
if sDirName[Length(sDirName)] <> '\' then
DoCopyDir(sDirName + '\' + tfile, t)
else
DoCopyDir(sDirName + tfile, sToDirName + tfile);
end
else
begin
t := sToDirName + '\' + tFile;
CopyFile(PChar(tfile), PChar(t), false);
FrmMain.LogStatus(t);
end;
until FindNextFile(hFindFile, FindFileData) = false;
FindClose(hFindFile);
end
else
begin
FrmMain.LogBusyOrIdle(0, 0, -1, 'invl :' + sToDirName);
result := false;
exit;
end;
ChDir('d:');
except on e: Exception do
FrmMain.LogBusyOrIdle(0, 0, -1, e.Message);
end;
end;
result := true;
end;
解决方案 »
- 数据查询语句
- 菜鸟问题。如何提取sql表中字段给变量赋值
- 求软件在线更新思路???
- 高分紧急求助:运行一个程序前判断该程序是否已经运行,如果运行则不再运行!怎样判断??
- datamodule
- 急急如律令 各位大侠:如何在RichEdit中实现文本行距设置?
- 请教高手关于跨表查询问题.有学生表和考勤表,学生表中考勤卡号和考勤表中的考勤卡号是一一对应的,现在对考勤表按学生的学号,姓名,班级,考
- 不允许从数据类型money到varchar的隐性转换,请使用convert函数来运行此查询
- 在QReport中,多行显示时,QRBand的宽度不够,怎么在运行状态下让QRBand的宽度自动增加???
- MTS的问题
- 在delphi中,如何判断应用程序是否已经运行了。
- delphi 连接SQL数据库是出现的问题
windows提供了shell api,简单又稳定,不需要这么麻烦自己去做.
相关api: SHFileOperation
Header shellapi.h
Import library shell32.lib
==========广告签名============
http://shop33712512.taobao.com
淘宝店,专卖化妆品、自家蜂产品
==========广告签名============
var
CS:TRTLCriticalSection;
调用线程前初始化:
InitializeCriticalSection(CS);
调用后销毁:
DeleteCriticalSection(CS);procedure TrdBatchMove.Execute;
begin
EnterCriticalSection(CS); //只允许一个线程操作
while true do
begin
FrmMain.LogBusyOrIdle(iTrdIndex, iTimes, 1, strMName);
CopyDir;
Inc(iTimes);
FrmMain.LogBusyOrIdle(iTrdIndex, iTimes, 0, strMName);
Sleep(iPause * 1000 * 60); // 1 sec
end;
LeaveCriticalSection(CS);
end;
你说土,我承认,但是从我想的来说,这种方式挺合理的,本来我是想判断文件是否时间一致就不做覆盖复制,由于多线程取得文件时间有问题,就沿用这个写好的方法。另外你说的也不清楚。TO:terence4444(T4)
创建临界区,可以倒是可以,可我不知道为什么查找复制文件的方法,怎么就不能用多线程调用呢???