我们有一个 Web 应用程序,它尝试在 Samba 挂载上使用一些资源。如果挂载以某种方式失败,我需要一种方法来快速检测并报告错误,但是当挂载消失时,File.Exists 和 Directory.Exists 需要 30 秒才能返回 false。在 C# 中快速确定挂载是否可用的最佳方法是什么?
4 回答
如果使用 File.Exists 成功检查总是在 5 秒(或更短的时间)内完成,您可以假设任何花费比这更长的调用都会失败。
这是一个伪代码可能的解决方案:
const int CUSTOM_TIMEOUT = 5;
bool isMountedVar = false;
bool isMounted ( string path) {
Thread mythread = executeNewThread(&isMountedThread, path);
sleep(CUSTOM_TIMEOUT);
if( mythread.finished() )
return isMountedVar;
// Otherwise
mythread.kill();
return false;
}
void isMountedThread(string path) {
isMountedVar = File(path).Exists;
}
Win32 Windows 网络功能是获取此信息的唯一方法。您应该能够使用WNetGetResourceInformation或WNetGetConnection。我认为 WNetGetConnection 可能是最好的选择。您最感兴趣的返回值是:
ERROR_CONNECTION_UNAVAIL
该设备当前未连接,但它是持久连接。有关详细信息,请参阅以下备注部分。
ERROR_NO_NETWORK
网络不可用。
除此之外,我理解希望能够主动从备份位置读取/写入的愿望,但在我看来,在硬件和/或操作系统方面而不是应用程序方面会更恰当地处理。硬件和/或操作系统更有可能检测到读/写失败或发生了一些其他网络相关事件并采取适当的措施。
问题在于底层操作系统 (Windows) 需要永远返回没有可用共享的事实。
我能想到的最快的方法是启动 ping 以查看是否从远程设备获得响应,如果 ping 成功(应该在一秒钟内验证),那么理论上你应该得到坐骑的反应相当快。如果远程设备不可用,那么您也会相对较快地产生某种想法。它很脏,但肯定会给您比等待 Windows 检查超时更快的结果。
这当然不会验证远程设备上共享的可用性......您是否有能力在远程服务器上运行软件?如果是这样,您可以编写一个可以检查共享可用性的哨兵,您可以使用共享名称 ping。然后理论上它会更快地响应,因为不需要超时 - 哨兵会以真假响应,或者无法立即响应。无论如何,您都会有一个快速的答案。
暂时就这些了……也许我很快就会有更多的想法。
我建议查看WIN32
Windows 网络功能,因为此功能不能直接从.NET
. 一个可能的起点是WNetGetResourceInformation
Function,它带有错误返回码。
WNetGetResourceInformation
当提供到网络资源的远程路径时,WNetGetResourceInformation 函数会识别拥有该资源的网络提供者并获取有关资源类型的信息。如果函数失败,则返回值为系统错误码,如以下值之一。
返回代码 - 说明
ERROR_BAD_NET_NAME - 输入 lpRemoteName 成员不是任何网络的现有网络资源。
ERROR_BAD_DEV_TYPE - 输入 dwType 成员与 lpRemoteName 成员指定的资源类型不匹配。
ERROR_EXTENDED_ERROR - 发生了特定于网络的错误。调用 WNetGetLastError 以获取错误描述。
ERROR_MORE_DATA - lpBuffer 参数指向的缓冲区太小。
ERROR_NO_NETWORK - 网络不可用。
为了调用Wnet
函数,请在Pinvoke.net.NET
上搜索示例。快速搜索了一下没有拿出例子,但是其他函数的调用已经够多了。有关类似用途,请参见WNetAddConnection2 。WNetGetResourceInformation
Wnet
该
WNetAddConnection2
函数与网络资源建立连接。该功能可以将本地设备重定向到网络资源。