2008-10-21 35 views
5

Trong ứng dụng của tôi, tôi có một chuỗi hiển thị một thời gian "vui lòng chờ" cửa sổ hộp thoại, đôi khi nó là một thời gian rất nhỏ và có một số trục trặc trong khi vẽ Giao diện người dùng (tôi đoán)."Chủ đề đã bị hủy bỏ" ngoại lệ trong khi hiển thị hộp thoại

Tôi nhận được ngoại lệ "Chủ đề đã bị hủy bỏ" và hoàn toàn không biết làm thế nào để loại bỏ nó. Tôi có nghĩa là Bắt ngoại lệ đó theo một cách nào đó, hoặc theo cách nào khác ẩn nó khỏi người dùng. Ngoại lệ này không liên quan gì đến phần còn lại của ứng dụng của tôi và lỗi đó theo bất kỳ cách nào không ảnh hưởng đến nó. Xuất hiện ngẫu nhiên và rất khó để tạo lại cuộc gọi.

Tôi đã thử theo nhiều cách khác nhau để bắt ngoại lệ đó bên cạnh mã bắt đầu và dừng luồng với cửa sổ hộp thoại nhưng dường như lỗi đó nằm bên cạnh một số luồng khác phân phối cửa sổ trong chuỗi mới tạo của tôi. Dưới đây là một mẫu mã, một phần của lớp tĩnh với các công cụ hữu ích, tất nhiên tôi không nói đó là cách tốt để giải quyết tình trạng "bận" này nhưng tôi muốn giải quyết vấn đề này. Thread.Sleep (500); hoặc các hiệu ứng try/catch khác không giúp tôi tránh được ngoại lệ của luồng đó.

public static bool alreadyBusy = false; 
    public static BusyIndicator bi = new BusyIndicator(""); 
    public static Thread backgroundOpertionThread; 

    public static void showBusy(bool isBusy, System.Windows.Forms.Form hostform, string message) 
    { 
     Common.busyMessage = message; 
     if (isBusy) 
     { 
      Common.alreadyBusy = true; 
      backgroundOpertionThread = new Thread(new ThreadStart(showBusy)); 
      Thread.Sleep(500); 
      if (hostform != null) 
      { 
       hostform.Enabled = false; 
       hostform.SuspendLayout(); 
      } 
      backgroundOpertionThread.Start(); 

     } 
     else 
     { 

      backgroundOpertionThread.Abort(); 
      Thread.Sleep(500); 
      Common.alreadyBusy = false; 
      if (hostform != null) 
      { 
       hostform.Enabled = true; 
       hostform.ResumeLayout(); 
      } 
     } 
    } 

    public static void showBusy() 
    { 
     BusyIndicator bir = new BusyIndicator(Common.busyMessage); 
     bir.ShowDialog(); 
    } 

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

+0

Bạn có thể cập nhật câu hỏi của mình bằng mẫu mã không? – jezell

Trả lời

15

Làm không sử dụng Thread.Abort. Phương pháp này được dành riêng khi thời gian chạy .NET cần phải loại bỏ các luồng để gỡ bỏ chương trình của bạn.

Bạn chỉ có thể "an toàn" sử dụng quyền này nếu bạn chuẩn bị hủy một AppDomain và muốn loại bỏ các chủ đề đang chạy trong đó trước tiên.

Để loại bỏ chuỗi, hãy viết chủ đề đó ở chế độ hợp tác. Điều này có nghĩa rằng các chủ đề nên định kỳ kiểm tra một số loại cờ, và nếu cờ được thiết lập, thoát ra bình thường ra khỏi phương pháp thread. Để "giết" chủ đề, chỉ cần đặt cờ và đợi cho chuỗi thoát.

Bạn có thể sử dụng đối tượng Sự kiện hoặc biến boolean đơn giản cho cờ này.

Nhưng không sử dụng Thread.Abort.

+2

+1. Và chỉ để nhấn mạnh: * Không sử dụng Thread.Abort! * :-) –

+2

Cách tiếp cận thoát chuỗi duyên dáng là tất cả tốt và tốt nếu một chuỗi thực sự có thể liên tục và đáng tin cậy kiểm tra giá trị của một lá cờ (ví dụ như trong một vòng lặp) , nhưng những gì về khi thread đang thực hiện một nhiệm vụ 'nâng hạng nặng' và bị khóa trên một dòng mã? Thread.Abort() là cách duy nhất tôi biết để chấm dứt một thread trong loại kịch bản này. Có cách nào khác có thể không? – Bosco

+2

Tôi muốn xem câu hỏi của Bosco đã trả lời. – jocull

1

sử dụng SafeThread và thiết lập ShouldReportThreadAbort false để làm cho vấn đề đi xa ...

một giải pháp tốt hơn sẽ được chạy trong trình gỡ lỗi với gỡ lỗi >> Exceptions >> Ném kiểm tra đối với tất cả các loại ngoại lệ, và tìm hiểu xem điều gì đang xảy ra để hủy bỏ chủ đề của bạn

CHỈNH SỬA: cảm ơn bạn đã đăng mẫu mã, điều này làm cho vấn đề dễ nhìn hơn nhiều. KHÔNG GỌI THREAD.ABORT

+0

Vấn đề là do đó exeption là khó để tái tạo, đặc biệt là trong Debug Enviromnent do chút chậm lại trên các hoạt động mà môi trường gỡ lỗi cung cấp. Tôi nhớ lỗi stacktrace nằm trong bản vẽ GUI của NET Framework trên mã của tôi – MoreThanChaos

+0

và ofcourse tôi cố gắng sử dụng lời khuyên của bạn, nhưng sẽ không có cách nào để thực hiện các kiểm tra chính xác, vì tôi đã nói rằng các yếu tố ngoại lệ khó tái tạo – MoreThanChaos

0

Đồng ý với ý tưởng của Steven về việc bật tất cả ngoại lệ khi được ném. Sau đó, bạn sẽ có thể thấy ngay vấn đề.

Một điều quan trọng cần nhớ, bạn sẽ không có tùy chọn menu gỡ lỗi nếu cài đặt studio hình ảnh của bạn nói chung, thay vì cài đặt "Visual C# Developer". Vẫn bắt tôi nếu tôi đang sử dụng máy mới hoặc sử dụng hồ sơ mới ...

+0

đã được thử trên hai máy khác nhau, ngoài ra vui lòng đọc nhận xét cho câu trả lời trước – MoreThanChaos

-3

Bạn có thể thử gọi

Thread.Sleep(500); 

sau

backgroundOpertionThread.Start(); 

này sẽ cung cấp cho các chủ đề nền 500 ms để làm những gì nó cần phải làm trước khi các chủ đề chính được một cơ hội để gọi

backgroundOpertionThread.Abort(); 

Chỉnh sửa: Nhưng tôi đồng ý rằng giải pháp tốt nhất sẽ không được sử dụng Thread.Abort() tại tất cả

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