【问题标题】:Using Directory.Exists on a network folder when the network is down网络中断时使用 Directory.Exists 在网络文件夹中
【发布时间】:2012-01-16 02:58:14
【问题描述】:

我公司的代码库包含以下 C# 行:

bool pathExists = Directory.Exists(path);

在运行时,字符串path 恰好是公司内部网上的文件夹地址——类似于\\company\companyFolder。当从我的 Windows 机器到 Intranet 的连接建立时,这工作正常。但是,当连接断开时(就像今天一样),执行上面的行会导致应用程序完全冻结。我只能通过使用任务管理器来关闭应用程序。

当然,在这种情况下,我宁愿让Directory.Exists(path) 返回false。有没有办法做到这一点?

【问题讨论】:

    标签: c# networking connection


    【解决方案1】:

    在这种情况下,无法更改 Directory.Exists 的行为。在引擎盖下,它通过网络在 UI 线程上发出同步请求。如果网络连接因中断、流量过多等而挂起……也会导致 UI 线程挂起。

    您能做的最好的事情是从后台线程发出此请求,并在经过一定时间后明确放弃。例如

    Func<bool> func = () => Directory.Exists(path);
    Task<bool> task = new Task<bool>(func);
    task.Start();
    if (task.Wait(100)) {
      return task.Value;
    } else {
      // Didn't get an answer back in time be pessimistic and assume it didn't exist
      return false;
    }
    

    【讨论】:

    • 这很容易耗尽线程池中的所有可用线程,从而导致应用程序中出现更多问题。如果您要执行此类操作,您需要能够在超时后终止操作。
    • @csharptest.net 这就是问题所在,但你不能。 Directory.Exists 方法无法控制超时,因为它本质上会立即下降到本机代码事件,Thread.Abort 对您没有帮助。
    【解决方案2】:

    如果一般网络连接是您的主要问题,您可以在此之前尝试测试网络连接:

        [DllImport("WININET", CharSet = CharSet.Auto)]
        static extern bool InternetGetConnectedState(ref int lpdwFlags, int dwReserved);
    
        public static bool Connected
        {
            get
            {
                int flags = 0;
                return InternetGetConnectedState(ref flags, 0);
            }
        }
    

    然后判断路径是否为UNC路径,如果网络离线则返回false:

        public static bool FolderExists(string directory)
        {
            if (new Uri(directory, UriKind.Absolute).IsUnc && !Connected)
                return false;
            return System.IO.Directory.Exists(directory);
        }
    

    当您尝试连接的主机处于离线状态时,这些都无济于事。在这种情况下,您仍然需要 2 分钟的网络超时。

    【讨论】:

      猜你喜欢
      • 2023-03-30
      • 2012-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-21
      • 2014-10-29
      相关资源
      最近更新 更多