我们有一个Web应用程序尝试在Samba挂载上使用某些资源。如果挂载以某种方式失败,我需要一种方法来快速检测并报告错误,但是当挂载消失时,File.Exists和Directory.Exists需要30秒才能返回false。快速确定C#中是否有可用的挂载的最佳方法是什么?
答案 0 :(得分:3)
如果使用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;
}
答案 1 :(得分:2)
Win32 Windows网络功能是获取此信息的唯一方法。您应该可以使用WNetGetResourceInformation或WNetGetConnection。我认为WNetGetConnection可能是最好的选择。您最感兴趣的返回值是:
ERROR_CONNECTION_UNAVAIL
设备当前未连接,但它是持久连接。有关更多信息,请参阅以下备注部分。
ERROR_NO_NETWORK
网络不可用。
除此之外,我理解主动能够从备份位置读取/写入的愿望,但在我看来,在硬件和/或操作系统方面可以更好地处理,而不是应用。硬件和/或操作系统更有可能检测到读/写失败或其他一些网络相关事件发生并采取相应的操作。
答案 2 :(得分:1)
问题在于底层操作系统(Windows)永远无法返回没有可用共享的事实。
我能想到的最快的方法是启动ping,看看你是否从远程设备得到响应,如果ping成功(这应该在一秒内可以验证),那么理论上你应该快速地从山上得到一个回应。如果远程设备不可用,那么你也会有一些相关的想法。它 脏,但肯定会比等待Windows检查超时更快给你结果。
这当然不会验证远程设备上共享的可用性......您是否能够在远程服务器上运行软件?如果是这样,您可以编写一个可以检查共享可用性的标记,您可以使用共享名称进行ping操作。然后它理论上会更快地响应,因为不需要超时 - 哨兵会以真或假的方式响应,或者无法立即响应。在任何情况下,你都有一个快速的答案。
这就是现在......也许我很快就会有更多的想法。
答案 3 :(得分:1)
我建议您查看WIN32
Windows Networking Functions,因为无法直接从.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
拨打.NET
个功能,请在Pinvoke.net上搜索示例。快速搜索未提供WNetGetResourceInformation
示例,但有足够的调用其他Wnet
函数。有关类似用途,请参阅WNetAddConnection2。
WNetAddConnection2
函数建立与网络资源的连接。该功能可以将本地设备重定向到网络资源。