2009-09-17 33 views
12

tôi sử dụngChức năng Trình khám phá thư mục nhanh hơn?

DirectoryExists (const PathName : String); 

để kiểm tra xem một thư mục có thể truy cập từ một máy tính hay không. Nhưng nếu thư mục không tồn tại và tên đường dẫn là đường dẫn mạng, nghĩa là

\\computer1\Data 

phương pháp này mất rất nhiều thời gian để quay trở lại.

Phải có cách nhanh hơn để xác định rằng thư mục mạng không thể truy cập được. Hoặc tôi có thể cấu hình một số tham số thời gian chờ mà DirectoryExists sử dụng nội bộ (tôi nhìn vào mã nguồn nhưng nó chỉ đại biểu cho GetFileAttributes được định nghĩa trong kernel32)?

Bất kỳ ý tưởng nào?

+0

Sự cố là thư mục không tồn tại trên máy tính từ xa hoặc bạn không thể kết nối với máy tính từ xa ngay từ đầu? –

+0

Có thể là cả hai, nhưng trong hầu hết các trường hợp tôi không thể kết nối. – jpfollenius

+0

Như một ví dụ ngược lại, tôi muốn đặt một NAS nhỏ ở nhà: Khi tôi không sử dụng nó trong một thời gian, các đĩa quay xuống. Khi lần đầu tiên tôi truy cập vào thư mục được gắn, danh sách đơn giản có thể mất khoảng 20 giây. Vì vậy, trong 20 giây đó không có cách nào để biết nếu có thư mục nào tồn tại trên đó. Ngay cả sau 15 giây bạn không thể chắc chắn rằng nó không tồn tại ... chỉ khi bạn nhận được một câu trả lời (tiêu cực) thực tế từ máy chủ, bạn có thể chắc chắn rằng tập tin không tồn tại. –

Trả lời

18

Không có cách nào nhanh hơn:

mọi chức năng truy cập mọi thứ trên chia sẻ từ xa sẽ hết thời gian chờ khi chia sẻ đó không khả dụng.

Nếu nguyên nhân của timeout của bạn là tự động ngắt kết nối của cổ phiếu, sau đó liên kết này có thể giúp bạn: http://support.microsoft.com/default.aspx?scid=kb;[LN];Q138365

Nếu ứng dụng có thể tiếp tục mà không hoàn thành việc kiểm tra, sau đó bạn có thể đặt dấu check ở một thread riêng biệt và sau khi hoàn thành kiểm tra, bạn có thể cập nhật trạng thái của mình trong giao diện người dùng.

--jeroen

5

Nếu bạn kiểm tra nhiều thư mục, bạn nên sử dụng chuỗi để thực hiện tất cả các truy vấn song song vì chia sẻ mạng thường là thời gian chờ dài.

+0

Tôi không thử nghiệm nhiều thư mục. Chỉ cho một. Nhưng DirectoryExists có thể mất khoảng 30 giây để quay trở lại, điều này gây phiền toái. – jpfollenius

6

Có những câu hỏi tương tự cho C#: How to avoid network stalls in GetFileAttributes?

Như codymanix nói, đề sử dụng. Liên kết ở trên sẽ chỉ cho bạn cách bạn có thể làm điều đó với các đại biểu trong C#. Bạn không biết Delphi, nhưng có thể bạn biết cách chuyển đổi mã?

+3

(chủ đề sẽ chỉ giúp đỡ nếu bạn có thể làm điều gì đó tương đương. Nếu hành động tiếp theo của bạn phụ thuộc vào phần chia sẻ (ví dụ để tải cấu hình), trong trường hợp chủ đề bạn chỉ có khả năng hiển thị cho người dùng một số chuyển động, nó không tăng tôc) –

3

Đây là cách tốt nhất. Bạn có thể thêm một số mã để ping máy để bảo đảm nó tồn tại, nhưng điều này vẫn sẽ để lại thường xuyên thất bại vì nhiều máy tính ngày nay có tường lửa phần mềm được thiết lập để bỏ qua các yêu cầu ping, cũng như khả năng chia sẻ được yêu cầu hiện hữu. Ngoài ra, trên một số máy nếu đường dẫn UNC nằm trên máy cục bộ và máy cục bộ không có thẻ mạng đang hoạt động (máy tính xách tay bị ngắt kết nối wi-fi chẳng hạn trong chế độ "Máy bay") thì yêu cầu UNC cũng sẽ không thành công .

0

Nếu cả hai máy tính trên cùng một tên miền, nó sẽ tăng tốc độ hoạt động của tệp khi xử lý các chia sẻ.

1

Trong tình huống tương tự như bạn đã quy định, trước tiên tôi đã thêm ping ICMP vào máy chủ. Nếu máy chủ không phản hồi lại ping, tôi giả sử nó bị hỏng. Bạn có thể quyết định thời gian chờ để sử dụng trên chính ping, vì vậy bạn có thể đặt thời gian chờ ngắn hơn nhiều so với thời gian chờ được sử dụng trong nội bộ khi cố mở một tệp chia sẻ.

2

tôi sử dụng đoạn mã sau ...

private delegate bool DirectoryExistsDelegate(string folder); 

bool DirectoryExistsTimeout(string path, int millisecondsTimeout) 
{ 
    try 
    { 
     DirectoryExistsDelegate callback = new DirectoryExistsDelegate(Directory.Exists); 
     IAsyncResult result = callback.BeginInvoke(path, null, null); 

     if (result.AsyncWaitHandle.WaitOne(millisecondsTimeout, false)) 
     { 
      return callback.EndInvoke(result); 
     } 
     else 
     { 
      callback.EndInvoke(result); // Needed to terminate thread? 

      return false; 
     } 
    } 

    catch (Exception) 
    { 
     return false; 
    } 
} 

... cho phép tôi có một phiên bản thời gian chờ của Directory.Exist. Tôi gọi nó bằng thứ gì đó như ...

bool a = DirectoryExistsTimeout("\\\\machine\\folder", 5000); 

Điều này có phù hợp với bạn không?


Để an toàn/hợp pháp thì bạn cần gọi "callback.EndInvoke (result);" nhưng gọi nó khóa cho đến khi async kết thúc để điều này đánh bại đối tượng của mã. Có lẽ điều này cần phải được thực hiện vào cuối mã của bạn - có thể thoát ra?

Các vấn đề liên quan