我用
DirectoryExists (const PathName : String);
检查目录是从计算机或无法访问。但是,如果该目录不存在和路径名的网络路径,即
\\computer1\Data
该方法需要很长的时间来恢复。
必须有确定的网络文件夹不可达更快的方法。或者,我可以配置DirectoryExists一些内置的超时参数(我看了看源代码,但是这是在KERNEL32定义,它只是委托给GetFileAttributes)?
有任何想法吗?
有没有更快的方法:
当共享不可用远程共享访问任何任何功能将超时。
如果超时的原因是股票自动断开,然后将这些链接可以帮助你:
如果应用程序可以继续,而不检查完成,那么你可以把检查在一个单独的线程,检查完成后,您可以更新用户界面中的状态。
请注意,当您尝试一个多线程的方式,你要反驳你的代码是免费的比赛条件和内存泄漏。与例外组合超时通常作出这样一个艰巨的任务。
有人支持C#同样的问题:How to avoid network stalls in GetFileAttributes?
作为codymanix说,使用线程。上面的链接会告诉你如何可以在C#中的代表做。不知道德尔福,但也许你知道如何将代码转换?
如果您测试大量的目录,你应该使用线程来完成所有的并行,是因为网络股疗法通常是长期超时查询。
这是最好的方式。你可以添加一些代码来ping计算机,以确保它的存在,但是这仍然会离开例行高达失败,因为许多计算机今天软件防火墙设置为忽略ping请求,以及可能请求该份额不存在。
此外,在一些机器上,如果UNC路径是在本地机器上,并在本地机器没有活动的网络卡(无线网络连接断开连接的笔记本电脑,例如在“飞机”模式),则UNC请求也将失败。
在类似的情况就像你规定的,我首先增加了一个ICMP的ping服务器。如果服务器不响应ping,我认为这是下跌。您可以决定在平自己使用的超时,所以你可以把它远比试图打开一个文件共享时内部使用的超时时间更短。
我使用下面的代码...
private delegate bool DirectoryExistsDelegate(string folder);
bool DirectoryExistsTimeout(string path, int millisecondsTimeout)
{
try
{
DirectoryExistsDelegate callback = new DirectoryExistsDelegate(Directory.Exists);
IAsyncResult result = callback.BeginInvoke(path, null, null);
if (result.AsyncWaitHandle.WaitOne(millisecondsTimeout, false))
{
return callback.EndInvoke(result);
}
else
{
callback.EndInvoke(result); // Needed to terminate thread?
return false;
}
}
catch (Exception)
{
return false;
}
}
......这让我有Directory.Exist的超时版本。我把它的东西,如...
bool a = DirectoryExistsTimeout("\\\\machine\\folder", 5000);
这会不会对你的需求确定?
为了安全起见/法律,那么你需要调用“callback.EndInvoke(结果);”但调用它锁定,直到异步完成所以这违背了代码的对象。也许这需要在你的代码到底做了些什么 - 也许退出?
如果两台计算机都在同一个域中的股份时,它会加快更新文件的操作。
此功能为我工作得非常好:NetDirectoryExists(Path, Timeout)
它使用线程,是TDirectory.Exists(Path)
完美替代
用法:
if NetDirectoryExists('\\computer1\Data', 1000) then ...
if NetDirectoryExists('C:\Folder', 500) then ...
如果该文件夹存在,该功能只需要几毫秒,同时与不存在的文件夹(C:\NotExisting
)。如果它是一个不可达网络路径(\\ServerNotReady\C$
),那么它会消耗由第二个参数给出的毫秒数。
Function NetDirectoryExists( const dirname: String;
timeoutMSecs: Dword ): Boolean;
implementation
uses
Classes, Sysutils, Windows;
type
ExceptionClass = Class Of Exception;
TTestResult = (trNoDirectory, trDirectoryExists, trTimeout );
TNetDirThread = class(TThread)
private
FDirname: String;
FErr : String;
FErrclass: ExceptionClass;
FResult : Boolean;
protected
procedure Execute; override;
public
Function TestForDir( const dirname: String;
timeoutMSecs: Dword ):TTestResult;
end;
Function NetDirectoryExists(
const dirname: String; timeoutMSecs: Dword ): Boolean;
Var
res: TTestResult;
thread: TNetDirThread;
Begin
Assert( dirname <> '', 'NetDirectoryExists: dirname cannot be empty.' );
Assert( timeoutMSecs > 0, 'NetDirectoryExists: timeout cannot be 0.' );
thread:= TNetDirThread.Create( true );
try
res:= thread.TestForDir( dirname, timeoutMSecs );
Result := res = trDirectoryExists;
If res <> trTimeout Then
thread.Free;
{Note: if the thread timed out it will free itself when it finally
terminates on its own. }
except
thread.free;
raise
end;
End;
procedure TNetDirThread.Execute;
begin
try
FResult := DirectoryExists( FDirname );
except
On E: Exception Do Begin
FErr := E.Message;
FErrclass := ExceptionClass( E.Classtype );
End;
end;
end;
function TNetDirThread.TestForDir(const dirname: String;
timeoutMSecs: Dword): TTestResult;
begin
FDirname := dirname;
Resume;
If WaitForSingleObject( Handle, timeoutMSecs ) = WAIT_TIMEOUT
Then Begin
Result := trTimeout;
FreeOnTerminate := true;
End
Else Begin
If Assigned( FErrclass ) Then
raise FErrClass.Create( FErr );
If FResult Then
Result := trDirectoryExists
Else
Result := trNoDirectory;
End;
end;