为非现有网络共享加速 File.Exists [英] Speed up File.Exists for non existing network shares

查看:19
本文介绍了为非现有网络共享加速 File.Exists的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须检查一组文件路径是否代表现有文件.

I have to check if a set of file paths represent an existing file.

它工作正常,除非路径包含不在当前网络上的机器上的网络共享.在这种情况下,超时需要很长时间(30 或 60 秒).

It works fine except when the path contains a network share on a machine that's not on the current network. In this case it takes a pretty long time (30 or 60 seconds) to timeout.

问题

  • 有没有办法缩短非现有网络共享的超时时间?(我敢肯定,当他们确实存在时,他们会很快回答,所以 1 秒的超时就可以了)

  • Is there a way to shorten the timeout for non existing network shares? (I'm certain that when they do exist they'll answer quickly, so a timeout of 1 sec would be fine)

有没有其他方法可以在不开始缓存并使算法更复杂的情况下解决这个问题?(即,我已经知道这些 X 网络共享不存在,跳过其余匹配路径)

Is there any other way to solve this issue without starting to cache and making the algorithm more complex? (ie, I already know these X network shares don't exist, skip the rest of the matching paths)

更新:使用线程工作,虽然不是特别优雅

UPDATE: Using Threads work, not particularly elegant, though

public bool pathExists(string path) 
{
    bool exists = true;
    Thread t = new Thread
    (
        new ThreadStart(delegate () 
        {
            exists = System.IO.File.Exists(path); 
        })
    );
    t.Start();
    bool completed = t.Join(500); //half a sec of timeout
    if (!completed) { exists = false; t.Abort(); }
    return exists;
}

此解决方案避免了每次尝试都需要线程,首先检查哪些驱动器可访问并将其存储在某处.

This solution avoids the need for a thread per attempt, first check which drives are reachable and store that somewhere.

首先,您可以在 IsDriveReady 函数中设置一个超时"值.我将它设置为 5 秒,但设置为适合您的任何方式.

First of all, there is a "timeout" value that you can set in the IsDriveReady function. I have it set for 5 seconds, but set it for whatever works for you.

下面使用了3种方法:

  1. 第一个是 WNetGetConnection API 函数,它获取驱动器的 UNC(servernameshare)
  2. 第二个是我们的主要方法:Button1_Click 事件
  3. 第三个是 ping 服务器的 IsDriveReady 函数.

这对我很有用!给你:

'This API Function will be used to get the UNC of the drive
Private Declare Function WNetGetConnection Lib "mpr.dll" Alias _
"WNetGetConnectionA" _
(ByVal lpszLocalName As String, _
ByVal lpszRemoteName As String, _
ByRef cbRemoteName As Int32) As Int32


'This is just a button click event - add code to your appropriate event
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

    Dim bIsReady As Boolean = False

    For Each dri As IO.DriveInfo In IO.DriveInfo.GetDrives()

        'If the drive is a Network drive only, then ping it to see if it's ready.
        If dri.DriveType = IO.DriveType.Network Then

            'Get the UNC (\servernameshare) for the 
            '    drive letter returned by dri.Name
            Dim UNC As String = Space(100)
            WNetGetConnection(dri.Name.Substring(0, 2), UNC, 100)

            'Presuming the drive is mapped \servernameshare
            '    Parse the servername out of the UNC
            Dim server As String = _
                 UNC.Trim().Substring(2, UNC.Trim().IndexOf("", 2) - 2)

            'Ping the server to see if it is available
            bIsReady = IsDriveReady(server)

        Else
            bIsReady = dri.IsReady

        End If

        'Only process drives that are ready
        If bIsReady = True Then
            'Process your drive...
            MsgBox(dri.Name & " is ready:  " & bIsReady)

        End If

    Next

    MsgBox("All drives processed")

End Sub

Private Function IsDriveReady(ByVal serverName As String) As Boolean
    Dim bReturnStatus As Boolean = False

    '***  SET YOUR TIMEOUT HERE  ***
    Dim timeout As Integer = 5    '5 seconds

    Dim pingSender As New System.Net.NetworkInformation.Ping()
    Dim options As New System.Net.NetworkInformation.PingOptions()

    options.DontFragment = True

    'Enter a valid ip address
    Dim ipAddressOrHostName As String = serverName
    Dim data As String = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
    Dim buffer As Byte() = System.Text.Encoding.ASCII.GetBytes(data)
    Dim reply As System.Net.NetworkInformation.PingReply = _
                pingSender.Send(ipAddressOrHostName, timeout, buffer, options)

    If reply.Status = Net.NetworkInformation.IPStatus.Success Then
        bReturnStatus = True

    End If

    Return bReturnStatus
End Function

推荐答案

使用线程进行检查.我认为线程可能会超时.

Use Threads to do the checks. I think that threads can be timed out.

这篇关于为非现有网络共享加速 File.Exists的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆