2010-05-11 35 views
8

Tôi có một số mã bắt đầu một vài chuỗi để cho phép thực thi, sau đó sử dụng vòng lặp while để kiểm tra thời gian hiện tại vượt qua khoảng thời gian chờ đã đặt hoặc cho số lượng kết quả chính xác đã được xử lý (bằng cách kiểm tra int trên đối tượng lớp) (với số Thread.Sleep() để chờ giữa các vòng)Tại sao mã của tôi dừng lại và không trả lại ngoại lệ?

Khi vòng lặp while được đặt để thoát, nó gọi số Abort() trên chủ đề và sẽ trả về dữ liệu cho hàm gọi phương thức.

Khi gỡ lỗi và bước qua mã, tôi thấy có thể có ngoại lệ trong mã chạy trên các chuỗi riêng biệt và trong một số trường hợp, tôi xử lý một cách thích hợp và vào những lúc khác, tôi không muốn làm gì cụ thể.

Điều tôi đã thấy là mã của tôi đi vào vòng lặp while và luồng ngủ, sau đó không có gì được trả lại từ hàm của tôi, dữ liệu hoặc ngoại lệ. Thực thi mã chỉ dừng hoàn toàn.

Bất kỳ ý tưởng nào có thể xảy ra?


mẫu Mã số:

System.Threading.Thread sendThread = 
    new System.Threading.Thread(new System.Threading.ThreadStart(Send)); 
sendThread.Start(); 

System.Threading.Thread receiveThread = 
    new System.Threading.Thread(new System.Threading.ThreadStart(Receive)); 
receiveThread.Start(); 

// timeout 
Int32 maxSecondsToProcess = this.searchTotalCount * timeout; 
DateTime timeoutTime = DateTime.Now.AddSeconds(maxSecondsToProcess); 
Log("Submit() Timeout time: " + timeoutTime.ToString("yyyyMMdd HHmmss")); 

// while we're still waiting to receive results & haven't hit the timeout, 
// keep the threads going 
while (resultInfos.Count < this.searchTotalCount && DateTime.Now < timeoutTime) 
{ 
    Log("Submit() Waiting..."); 
    System.Threading.Thread.Sleep(10 * 1000); // 1 minute 
} 

Log("Submit() Aborting threads"); // <== this log doesn't show up 

sendThread.Abort(); 
receiveThread.Abort(); 

return new List<ResultInfo>(this.resultInfos.Values); 
+0

Bạn không nên sử dụng Thread.Abort, làm một google vì lý do tại sao. –

+2

10 * 1000 không phải là phút :) (1000 * 60 ms = 60 s = 1 phút) – Simon

+0

Có tôi biết :) Tôi đã thay đổi mục này cho mục đích thử nghiệm nhưng không bao giờ cập nhật nhận xét .... – BeckyLou

Trả lời

3

Thread.Abort Tăng một ThreadAbortException trong các chủ đề mà nó được gọi

Bạn không nên để cho trường hợp ngoại lệ thoát khỏi chủ đề bạn đã bao giờ - bạn nên có xử lý ngoại lệ trong đối tượng luồng của bạn. Ít nhất phải có một khối try \ catch xung quanh mã trong đối tượng luồng.

+0

Cảm ơn, vâng chủ đề là vòng lặp và thử/nắm bắt trong vòng lặp. Một ThreadAbortException kết thúc phương thức và các ngoại lệ khác được nuốt hoặc ghi lại. – BeckyLou

5

Vì vậy, bạn thực sự không nên sử dụng phương thức Ngủ trên luồng cho mục đích đồng bộ hóa. Đây là các lớp đồng bộ hóa như ManualResetEvent cho, cũng như Mô hình lập trình không đồng bộ (triển khai IAsyncResult).

Cách tiếp cận tốt hơn ở đây là tạo đại biểu có chữ ký của phương thức bạn muốn chạy không đồng bộ. Sau đó, gán nhóm phương thức là điểm vào cho thao tác không đồng bộ vào một cá thể của ủy nhiệm đó và gọi BeginInvoke trên cá thể ủy nhiệm.

Từ đó, bạn sẽ chạy vòng lặp của mình, hy vọng bạn sẽ gọi quá tải WaitOne trên WaitHandle được trả về bởi thuộc tính AsyncWaitHandle của việc triển khai IAsyncResult được trả về bằng lệnh gọi BeginInvoke trên đại biểu.

Điều này sẽ ít phụ thuộc vào phương thức Ngủ (điều này không tốt cho việc đồng bộ hóa nói chung).

Nếu bạn có tùy chọn để sử dụng .NET 4.0, thì bạn có thể muốn xem Task class trong System.Threading.Tasks namespace vì nó cung cấp cách tốt hơn để xử lý việc xử lý không đồng bộ, hủy và chờ thời gian chờ.

+0

Cảm ơn vì điều này, trước đây tôi đã sử dụng các đại biểu để lập trình không đồng bộ, nhưng làm cách nào tôi vẫn có thể áp dụng thời gian chờ của mình để ngừng xử lý sau một khoảng thời gian nhất định trên cả hai đại biểu? – BeckyLou

+0

@BeckyLou: Chủ đề.Hủy bỏ chắc chắn là * sai * cách để làm điều đó, vì nó không phải là một lối ra duyên dáng. Giống như bất kỳ chương trình không đồng bộ nào, bạn sẽ phải đồng bộ hóa quyền truy cập vào một lá cờ từ chuỗi chờ và chuỗi đang thực hiện công việc. Nếu bạn hủy bỏ, bạn viết từ các chủ đề chờ đợi, và sau đó các chủ đề làm công việc kiểm tra cờ định kỳ để xem nếu nó nên ngừng làm việc. Thư viện Task Parallel (lớp Task) trong .NET 4.0 có rất nhiều điều này được xây dựng cho bạn, vì vậy tôi đề nghị bạn nên xem xét điều đó, nếu có thể. – casperOne

+0

Xin cảm ơn, tôi sẽ thử đề xuất của bạn. – BeckyLou

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