10

Tôi đang làm việc với các thành phần sau:BackgroundWorker xử lý ngoại lệ

  • một thư viện (mà ném một ngoại lệ)
  • một thử nghiệm giao diện điều khiển để kiểm tra đăng nhập của tôi
  • thư viện doanh nghiệp khối ứng dụng xử lý ngoại lệ
  • khối ứng dụng ghi nhật ký thư viện doanh nghiệp

Tôi đang gọi phương thức thư viện bằng cách sử dụng một người làm việc nền. Thư viện ném ngoại lệ nhưng trình xử lý RunWorkerCompleted không bao giờ được gọi.

Cách duy nhất để bắt ngoại lệ là bao quanh mã trình xử lý DoWork của tôi bằng khối try/catch.

Đã hiểu sai thuộc tính RunWorkerCompletedEventArgs.Error chưa? Không phải là nó để nhận được ngoại lệ đã bị bắt bởi BackgroundWorker?

Codesample:

static BackgroundWorker w = new BackgroundWorker(); 

w.DoWork += new DoWorkEventHandler(w_DoWork); 
w.RunWorkerCompleted += 
    new RunWorkerCompletedEventHandler(w_RunWorkerCompleted); 
w.RunWorkerAsync(); 



static void w_DoWork(object sender, DoWorkEventArgs e) 
{ 
    MyClass m = new MyClass(); 
    w.result = m.Compute(); 
} 

static void w_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    if (e.Error != null) 
    { 
     HandleException(e.Error); 
    } 

    /* result related code */ 

} 


static void HandleException(Exception e) 
{ 
    ExceptionPolicy.HandleException(e, "MyPolicy"); 
} 

Các ví dụ trên dẫn đến một kết thúc ứng dụng giao diện điều khiển của tôi. Đầu ra vs2010 hoàn toàn không viết gì (chỉ có đầu ra mặc định).

Vậy vấn đề ở đâu?

// Chỉnh sửa: đoạn mã này hoạt động để bắt ngoại lệ của thư viện.

static void w_DoWork(object sender, DoWorkEventArgs e) 
{ 
    try 
    { 
     MyClass m = new MyClass(); 
     w.result = m.Compute(); 
    }catch(Exception e){ } 

} 
+1

Bạn có thứ gì đó trên chủ đề chính ngăn không cho nó kết thúc? Một cái gì đó giống như một thời gian (đúng)? – dcarneiro

+0

Bạn có chắc chắn 100% rằng RunWorkerCompleted không bao giờ được gọi? Đây là một câu hỏi SO chứng minh điều này sẽ làm việc ... http: //stackoverflow.com/questions/1044460/unhandled-exceptions-in-backgroundworker –

+1

bạn không thể gỡ lỗi và xem những gì sẽ xảy ra? những gì HandleException() trả về? – Reniuz

Trả lời

7

Đó là mẫu chính xác cho BackgroundWorker.

Tôi nghi ngờ vấn đề là phương pháp Main của bạn là thoát trước khi BW hoàn tất.

RunWorkerAsync sẽ trả lại ngay lập tức và nếu bạn không chờ đợi trong Main, thì quá trình của bạn sẽ kết thúc, có lẽ ngay cả trước khi BW bắt đầu, đừng bận tâm.

Thử thêm Console.ReadLine vào cuối phương thức Main của bạn.


Ra quan tâm:

BW cư xử khác nhau trong một ứng dụng Console và một ứng dụng Windows. Nếu bạn sử dụng một ứng dụng WinForms hoặc WPF, sẽ có một SynchronizationContext có nguồn gốc trên chuỗi giao diện người dùng của bạn và BW sẽ sắp xếp lại một chuỗi giao diện người dùng và chạy nó ở đó. Đó là một trong những lợi ích chính của BW.

Trong ứng dụng giao diện điều khiển, SynchronizationContext mặc định được sử dụng và các nguyên soái này RunWorkerCompleted vào chuỗi chủ đề chuỗi. Điều này có nghĩa là bạn có thể chặn luồng Main và trình xử lý hoàn tất sẽ vẫn chạy.

+0

Cảm ơn bạn rất nhiều :) – csteinmueller

+0

Tôi đã sử dụng ứng dụng Console vì đây là cách nhanh nhất để kiểm tra thư viện. Tôi mất nhiều thời gian hơn để trình bày kết quả của mình trong một ứng dụng WPF. – csteinmueller

+7

@MartinJames Tôi dành một phần đáng kể thời gian viết ứng dụng giao diện điều khiển được lên lịch và chạy trên máy chủ. Giao diện người dùng sẽ không hữu ích hoặc không khả thi cho các tình huống như vậy. Nó cũng dễ dàng hơn để làm các bài kiểm tra đơn giản trong một ứng dụng bàn điều khiển; ít chi phí liên quan chỉ để làm một cái gì đó đơn giản và xem kết quả. – Servy