2010-03-22 17 views
7

Tôi có ứng dụng này sẽ recurse tất cả các thư mục trong một thư mục nhất định và tìm PDF. Nếu một tập tin PDF được tìm thấy, ứng dụng sẽ đếm các trang của nó bằng cách sử dụng ITextSharp. Tôi đã làm điều này bằng cách sử dụng một thread để đệ quy quét tất cả các thư mục cho pdf, sau đó nếu sau đó PDF được tìm thấy, điều này sẽ được xếp hàng đợi vào hồ bơi thread. Mã trông giống như sau:Làm thế nào để biết nếu tất cả các chủ đề của Thread Pool đã được thực hiện với nhiệm vụ của nó?

//spawn a thread to handle the processing of pdf on each folder. 
       var th = new Thread(() => 
       { 
        pdfDirectories = Directory.GetDirectories(pdfPath); 
        processDir(pdfDirectories); 
       }); 
       th.Start(); 



private void processDir(string[] dirs) 
     { 
      foreach (var dir in dirs) 
      { 
       pdfFiles = Directory.GetFiles(dir, "*.pdf"); 
       processFiles(pdfFiles); 

       string[] newdir = Directory.GetDirectories(dir); 
       processDir(newdir); 
      } 
     } 



private void processFiles(string[] files) 
     { 
      foreach (var pdf in files) 
      { 
       ThreadPoolHelper.QueueUserWorkItem(
        new { path = pdf }, 
        (data) => { processPDF(data.path); } 
        ); 
      } 
     } 

Vấn đề của tôi là, làm cách nào để biết người dùng đã hoàn thành việc xử lý tất cả các mục đã được xếp hàng?

Trả lời

4

Nói chung tôi sẽ làm một việc như thế này bằng cách có biến số lượt truy cập. Đối với mỗi mục công việc bạn xếp hàng trong các ThreadPool thêm một vào biến truy cập. Sau đó, khi được xử lý, bạn sẽ giảm biến số lượt truy cập.

Đảm bảo rằng bạn thực hiện tăng và giảm theo các phương thức trên lớp Interlocked vì điều này sẽ đảm bảo rằng mọi thứ được thực hiện theo cách an toàn.

Khi hit truy cập bằng không bạn có thể lá cờ mà các nhiệm vụ được hoàn thành bằng cách sử dụng ManualResetEvent

Nếu bạn có quyền truy cập vào NET 4 thì bạn có thể sử dụng lớp mới CountdownEvent để làm một điều tương tự.

+0

Tôi đã thực hiện một logic tương tự như thế này. Chỉ có tôi sử dụng ThreadPool.GetAvailableThreads. Tôi thiết lập các MaxThreads các hồ bơi nên được sử dụng bởi 20. Vì vậy, ở cuối cùng của nhiệm vụ tôi kiểm tra xem các chủ đề có sẵn bằng với tối đa mà tôi đặt. Thật không may điều này không thành công. Tôi sẽ nghiên cứu về Sự kiện đặt lại thủ công đó. –

+1

@mcxiand: Bạn không thể sử dụng bộ đếm ThreadPool vì mã khác (lib) có thể tạo chủ đề và TP đang tái chế/xóa chúng. –

+0

@ Henk Holterman: Vậy sao? Từ những gì tôi hiểu là, ThreadPool sẽ được xếp hàng đợi của nhiệm vụ bằng phương thức QueueUserWorkItem. Bạn có thể cung cấp thêm chi tiết về nhận xét của mình không? nó sẽ được rất nhiều đánh giá cao. –

2

1) Làm cách nào để biết tất cả các chuỗi đã hoàn tất?

Bạn sẽ phải để cho các Chủ đề làm riêng check-in/check-out của họ, bởi bracketing mã của bạn giữa:

Interlocked.Increment(ref jobCounter); 
// your code 
Interlocked.Decrement(ref jobCounter); 

Nếu đây messes lên các đại biểu vô danh của bạn quá nhiều thì chỉ cần sử dụng các phương pháp wrapper. Bạn có lẽ sẽ phải thêm xử lý ngoại lệ.

Cách tiếp cận liên khóa vẫn lắng nghe vấn đề chờ đợi nó trở thành 0, vòng lặp với Sleep() là yếu nhưng trong trường hợp này là giải pháp khả thi.

2) Bạn đang bắt đầu chủ đề trong bộ tập hợp cây đệ quy. Hãy cẩn thận, có thể bạn đang tạo ra quá nhiều và điều đó sẽ làm tổn thương hiệu suất.

+0

tôi chỉ có một chuỗi để thực hiện việc đệ quy và xếp hàng mọi tệp pdf được tìm thấy trong mỗi thư mục theo chuỗi –

+0

OK, nó tuyến tính hơn. Và từ các bình luận bạn tăng tốc MaxThreads. Vẫn yêu cầu điều chỉnh và thay đổi MaxThreads là một sledgehammer. –

+0

Tôi kiểm soát MaxThreads vì trên chủ đề này, tôi đang cập nhật kiểm soát giao diện người dùng bằng cách sử dụng BeginInvoke. Giao diện người dùng sẽ đóng băng nếu có nhiều chuỗi chạy. Bất kỳ đề xuất? –

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