2010-03-08 28 views
5

Tôi đang sử dụng nhiều luồng trong ứng dụng của tôi bằng cách sử dụng vòng lặp (true) và bây giờ tôi muốn thoát khỏi vòng lặp khi tất cả các chủ đề đang hoạt động hoàn thành công việc của họ.Làm thế nào để bạn xác định xem các chủ đề con đã hoàn thành

+0

Không hoàn toàn khác nhau từ câu hỏi này & trả lời: http://stackoverflow.com/questions/435668/code-for-a-simple-thread-pool -in-c – xcud

+0

Vòng lặp của bạn như thế nào? Bạn đang sử dụng nó để tạo chủ đề? Hay bạn đang sử dụng nó để chờ các chủ đề hoàn thành nhiệm vụ? – ata

Trả lời

1

Bạn có thể sử dụng Process.GetCurrentProcess(). Threads.Count.

+0

Giải pháp Process.GetCurrentProcess(). Threads.Count không hoạt động. Nó trả về tất cả các tiến trình đang chạy nhưng tôi cần đếm các luồng chạy mà tôi đã tạo trong ứng dụng của mình. –

+0

Process.GetCurrentProcess() Threads.Count thực sự trả về số luồng cho quá trình hiện tại, nếu bạn cần đếm tất cả các luồng của tất cả các tiến trình bạn cần lặp lại quy trình suy nghĩ trong ứng dụng của bạn – Anonymous

+0

Điều đó cũng sẽ liên quan đến luồng thread. Mặc dù bạn có thể nhận được số đếm trước khi tạo chuỗi nhưng vẫn không đảm bảo rằng chuỗi chủ đề tùy chỉnh của bạn bị chấm dứt khi số lượng giảm. – ata

1

Có cách tiếp cận khác nhau ở đây, nhưng utlimately nhất trong số họ đi xuống để thay đổi đề thi của bạn để làm một cái gì đó bất cứ khi nào họ rời khỏi (thành công hay qua ngoại lệ, mà bạn không muốn làm anyway). Một cách tiếp cận đơn giản có thể là sử dụng Interlock.Decrement để giảm số lượt truy cập - và nếu đó là số không (hoặc -ve, có thể là lỗi), hãy giải phóng một đối tượng ManualResetEvent hoặc Monitor.Pulse; trong cả hai trường hợp, chủ đề gốc sẽ đợi trên đối tượng đó. Một số cách tiếp cận như vậy là discussed here.

Tất nhiên, có thể dễ dàng xem xét các bit TPL trong 4.0, cung cấp nhiều tùy chọn mới ở đây (không phải những thứ như Parallel.For trong PLINQ).

Nếu bạn đang sử dụng hàng đợi công việc đã đồng bộ hóa, bạn cũng có thể đặt hàng đợi đó để đóng (thoát) chính nó và chỉ cần đợi hàng đợi trống? Giả định ở đây là các chuỗi công nhân của bạn đang làm một việc gì đó như:

T workItem; 
while(queue.TryDequeue(out workItem)) { // this may block until either something 
    ProcessWorkItem(workItem);   // todo, or the queue is terminated 
} 
// queue has closed - exit the thread 

trong trường hợp này, hàng đợi trống rỗng, tất cả các chuỗi công nhân của bạn phải đang trong quá trình tự sát.

5

Giả sử rằng bạn có danh sách các chủ đề, đây là hai cách tiếp cận.

Giải pháp đầu tiên:

Sử dụng Thread.Join() với một tham số khoảng thời gian để đồng bộ với mỗi chủ đề lần lượt. Giá trị trả lại cho bạn biết liệu luồng đã kết thúc hay chưa.

Giải pháp thứ hai:

Kiểm tra Thread.IsAlive() để xem các chủ đề vẫn chạy.

Trong cả hai trường hợp, đảm bảo rằng chuỗi chính của bạn mang lại thời gian xử lý cho các chuỗi đang chạy, vòng lặp chờ của bạn sẽ tiêu thụ hầu hết/tất cả CPU và làm hỏng luồng công nhân của bạn.

+0

Trong trường hợp Join, thread gọi phương thức Join sẽ đợi cho nó trở lại. Trong trường hợp Thread.IsAlive, bạn sẽ phải thăm dò một số thời gian cụ thể (như 1 giây). Nó sẽ giống như gọi phương thức Join, chuỗi gọi sẽ phải chờ cho đến khi tất cả các luồng kết thúc. Sử dụng tốt hơn Thread.Join() – ata

+0

Sự khác biệt chính là việc bỏ phiếu IsAlive() cho phép chủ đề chính của bạn tiếp tục thực hiện công việc khác, nếu có. Điểm tốt mặc dù - nếu không có việc phải làm, Join() là lựa chọn hiệu quả hơn. – Bevan

0

Bạn có thể sử dụng Thread.Join(). Phương thức Join sẽ chặn chuỗi gọi cho đến khi chuỗi (phương thức mà phương thức Join được gọi) chấm dứt.

Vì vậy, nếu bạn có danh sách chuỗi, bạn có thể lặp lại và gọi Join trên mỗi chuỗi. Bạn vòng lặp sẽ chỉ thoát khi tất cả các chủ đề đã chết. Một cái gì đó như thế này:

for(int i = 0 ;i < childThreadList.Count; i++) 
{ 
    childThreadList[i].Join(); 
} 
///...The following code will execute when all threads in the list have been terminated.../// 
0

Tôi thấy rằng việc sử dụng phương thức Join() là cách sạch nhất. Tôi sử dụng nhiều chủ đề thường xuyên, và mỗi luồng thường tải dữ liệu từ các nguồn dữ liệu khác nhau (Informix, Oracle và SQL cùng một lúc.) Một vòng lặp đơn giản, như đã đề cập ở trên, gọi Join() trên mỗi đối tượng thread (mà tôi lưu trữ một đối tượng List đơn giản) hoạt động !!!

Carlos Merighe.

0

Tôi thích sử dụng một HashSet of Threads:

// create a HashSet of heavy tasks (threads) to run 
HashSet<Thread> Threadlist = new HashSet<Thread>(); 
Threadlist.Add(new Thread(() => SomeHeavyTask1())); 
Threadlist.Add(new Thread(() => SomeHeavyTask2())); 
Threadlist.Add(new Thread(() => SomeHeavyTask3())); 

// start the threads 
foreach (Thread T in Threadlist) 
    T.Start(); 

// these will execute sequential 
NotSoHeavyTask1(); 
NotSoHeavyTask2(); 
NotSoHeavyTask3(); 

// loop through tasks to see if they are still active, and join them to main thread 
foreach (Thread T in Threadlist) 
    if (T.ThreadState == ThreadState.Running) 
    T.Join(); 

// finally this code will execute 
MoreTasksToDo(); 
Các vấn đề liên quan