Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 访问断开连接的驱动器时,程序冻结30秒_Delphi - Fatal编程技术网

Delphi 访问断开连接的驱动器时,程序冻结30秒

Delphi 访问断开连接的驱动器时,程序冻结30秒,delphi,Delphi,我有一段让我发疯的代码 FUNCTION DiskInDrive(CONST DriveNumber: Byte): BOOLEAN; VAR ErrorMode : Word; BEGIN RESULT:= FALSE; ErrorMode := SetErrorMode(SEM_FAILCRITICALERRORS); TRY if DiskSize(DriveNumber) <> -1 { %%%% THIS IS VERY SLOW IF THE DI

我有一段让我发疯的代码

FUNCTION DiskInDrive(CONST DriveNumber: Byte): BOOLEAN;
VAR ErrorMode  : Word;
BEGIN
  RESULT:= FALSE;
  ErrorMode := SetErrorMode(SEM_FAILCRITICALERRORS);
  TRY
    if DiskSize(DriveNumber) <> -1  { %%%% THIS IS VERY SLOW IF THE DISK IS NOT IN DRIVE !!!!!! }
    THEN RESULT:= TRUE;
  FINALLY
    SetErrorMode(ErrorMode);
  END;
END;
函数DiskInDrive(CONST DriveNumber:Byte):布尔值;
VAR错误模式:Word;
开始
结果:=假;
ErrorMode:=设置错误模式(SEM\U故障临界错误);
尝试
如果DiskSize(DriveNumber)-1{%%%%,如果磁盘不在驱动器中,则速度非常慢!!!!}
然后结果:=真;
最后
设置错误模式(错误模式);
结束;
结束;
它检查磁盘是否准备好使用(以及提供的驱动器号是否与有效磁盘对应)。 问题是,当我尝试访问断开连接的网络驱动器(映射为驱动器的网络文件夹)时,它会冻结约10-30秒

代码在我制作的组件的构造函数中


我怎样才能在不等待那么长时间的情况下检查驱动器?

首先,你必须意识到你必须等待。访问未缓存的可移动媒体是一项昂贵的操作,这取决于许多不同的因素(驱动程序、制造商、媒体质量、操作系统版本、服务包、安装的防病毒软件等)

一旦你接受了这一点,你就不必让你的应用程序真正冻结。我这里没有德尔菲,但我要做的是

  • 创建一个新的
    tthreadeobject
    ,并将
    DiskInDrive
    逻辑放入其执行方法中
  • 使用变量设置/获取此结果
  • 启用/禁用相应的视觉控件

这样,您仍然需要等待,但应用程序不会失去响应。您甚至可以添加取消操作的选项(以防操作需要太长时间才能完成)。

据我所知,在Windows尝试访问网络驱动器时,对网络驱动器执行某些操作可能会锁定调用线程,这是不可避免的。这是乔尔·斯波尔斯基所说的其中之一


最好是从单独的线程执行驱动器检查,这样就不会锁定UI。(Delphi 2009的泛型或Jon Schemitz的库可以简化必要的多线程代码。)

在Delphi中创建一个具有工作线程的组件,并将对该函数的调用替换为对从池中创建或拾取工作线程的例程的调用,然后开始此工作。然后,如果代码超时,则返回FALSE。所以,如果磁盘超时,它就不在驱动器中


代码将在其时间内完成,并将线程返回到池中

你不能;这适用于本地和网络资源。另请参阅此问题的答案:在单独的线程中解决此问题(如果您检查多个设备:每个线程一个设备),代码已经在我制作的组件的构造函数中。