CreateProcess .. WaitForSingleObject .. CloseHandle 调用的最佳 try..finally 位置
Posted
技术标签:
【中文标题】CreateProcess .. WaitForSingleObject .. CloseHandle 调用的最佳 try..finally 位置【英文标题】:Optimal try..finally placement for CreateProcess .. WaitForSingleObject .. CloseHandle calls 【发布时间】:2015-05-02 13:57:09 【问题描述】:我想在调用 CreateProcess ..WaitForSingleObject 后调用 CloseHandle,并希望将 CloseHandle 调用包含在 try..finally 块中,但不确定将不同调用放在哪里 w.r.t。试试..最后。
这是我当前的代码:
var
p, f, a: String;
pi: TProcessInformation;
si: TStartupInfo;
begin
Log('Starting backup..');
if (not FileExists(FMYPROG)) then
begin
Log('Error: ' + STR_ERRMSG_1);
MessageDlg(STR_ERRMSG_1, mtError, [mbOK], 0);
Exit;
end;
// start process up
FillChar(si, SizeOf(si), 0);
si.cb := SizeOf(si);
si.dwFlags := STARTF_USESHOWWINDOW;
si.wShowWindow := SW_NORMAL;
f := IncludeTrailingPathDelimiter(FBAKFILEPATH) + 'output.bak';
p := '/changesonly "' + f + '"';
try // is this the optimal placement for this line? or should it be after CreateProcess?
if CreateProcess(PChar(FMYPROG), PChar(p), nil, nil, False,
CREATE_NEW_PROCESS_GROUP + NORMAL_PRIORITY_CLASS, nil, PChar(ExtractFilePath(FMYPROG)), si, pi) then
WaitForSingleObject(pi.hProcess, INFINITE)
else
RaiseLastOSError;
finally
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
end;
寻求导致德尔福启蒙的建议和批评。谢谢。
【问题讨论】:
写if not CreateProcess(...) then RaiseLastOSError; try..finally CloseHandles; end;
因为即使CreateProcess
失败,您也会关闭这些句柄。
顺序始终相同:AcquireResource; try UseResource; finally ReleaseResource; end
。这适用于您拥有的任何类型的资源(在您的情况下,进程和线程句柄)。您只需决定获取、使用和释放它们意味着什么。
【参考方案1】:
只有在CreateProcess
成功时才调用CloseHandle
。因此它是这样的:
if CreateProcess(...) then
try
....
finally
// calls to CloseHandle
end
else
RaiseLastOSError;
或者,如果您更愿意预先处理错误情况:
if not CreateProcess(...) then
RaiseLastOSError;
try
....
finally
// calls to CloseHandle
end
这在语义上是相同的,因为您知道RaiseLastOSError
会引发异常。
或者我更喜欢:
Win32Check(CreateProcess(...));
try
....
finally
// calls to CloseHandle
end;
Win32Check
便利函数只是简单地封装了逻辑
if not Succeeded then
RaiseLastOSError;
【讨论】:
这与 TLama 对该问题的评论不同。等着看他的理由。 不,本质上是一样的。要点是在CreateProcess
失败时跳过try..finally
块。在这篇文章中使用else
来引发异常。但是,即使您只是在输入异常之前引发异常,您也会跳过该块(这就是第二个 sn-p 所做的)。我已经放弃了我的答案草稿...
@Steve 是的,它是一样的。关键是只有在 CreateProcess 成功时才会执行 try。我将添加第三个选项。以上是关于CreateProcess .. WaitForSingleObject .. CloseHandle 调用的最佳 try..finally 位置的主要内容,如果未能解决你的问题,请参考以下文章