Ответ 1
Используйте Threads для выполнения проверок. Я думаю, что потоки могут быть отключены.
Мне нужно проверить, представляет ли набор путей файлов существующий файл.
Он отлично работает, за исключением случаев, когда путь содержит сетевой ресурс на компьютере, который не находится в текущей сети. В этом случае требуется довольно долгое время (30 или 60 секунд) до истечения времени ожидания.
Вопросы
Есть ли способ сократить время ожидания для не существующих сетевых ресурсов? (Я уверен, что когда они действительно существуют, они ответят быстро, поэтому тайм-аут в 1 секунду будет в порядке)
Есть ли другой способ решить эту проблему без начала кэширования и сделать алгоритм более сложным? (т.е. я уже знаю, что эти сетевые ресурсы X не существуют, пропустите остальные пути сопоставления)
UPDATE: использование Threads работает, но не особенно элегантно, хотя
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;
}
Это решение позволяет избежать необходимости в потоке за попытку, сначала проверить, какие диски доступны, и сохранить где-нибудь.
Прежде всего, есть значение "тайм-аута", которое вы можете установить в функции IsDriveReady. Я устанавливаю его на 5 секунд, но устанавливаю его для любых работ для вас.
3 метода используются ниже:
- Первой является функция API WNetGetConnection, которая получает UNC (\ имя_сервера\общий) диска
- Второй наш основной метод: событие Button1_Click
- Третья - это функция 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 ready. If dri.DriveType = IO.DriveType.Network Then 'Get the UNC (\\servername\share) 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 \\servername\share ' 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
Используйте Threads для выполнения проверок. Я думаю, что потоки могут быть отключены.
UNC
.ping
диск.если Google не является реферирующим, EE не показывает ответ бесплатно. Ссылки на EE не помогают.
OP нашел статью, о которой я упоминал в своем первоначальном ответе, и был достаточно любезен, чтобы включить исходный код для решения в свой вопрос.
Это работало для меня БОЛЬШИМ!
Здесь IsDriveReady() в С#:
using System.Net;
private bool IsDriveReady(string serverName)
{
// *** SET YOUR TIMEOUT HERE ***
int timeout = 5; // 5 seconds
System.Net.NetworkInformation.Ping pingSender = new System.Net.NetworkInformation.Ping();
System.Net.NetworkInformation.PingOptions options = new System.Net.NetworkInformation.PingOptions();
options.DontFragment = true;
// Enter a valid ip address
string ipAddressOrHostName = serverName;
string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
byte[] buffer = System.Text.Encoding.ASCII.GetBytes(data);
System.Net.NetworkInformation.PingReply reply = pingSender.Send(ipAddressOrHostName, timeout, buffer, options);
return (reply.Status == System.Net.NetworkInformation.IPStatus.Success);
}
Я нашел pathExists с функцией тайм-аута потока полезной, но, наконец, понял, что для изменения работы File.Exists в Directory.Exists необходимо правильно работать.
Не могли бы вы просто использовать элемент управления FileMonitor для этого, чтобы событие срабатывало, когда оно удаляется? Затем вы можете установить bool в false,