2013-05-17 37 views
5

Thông thường, đối với mã mà tôi không mong đợi để ném ngoại lệ nhưng (ví dụ: lỗi lập trình), tôi muốn ứng dụng của tôi bị lỗi (để nó không 't dữ liệu bị hỏng, báo cáo dữ liệu không hợp lệ cho người dùng, v.v.).Nhận ngoại lệ không mong muốn của Task để gỡ ứng dụng sớm hơn Garbage Collection

Có cách nào hay nhất để nhận được (gần hơn) hành vi này khi sử dụng Tasks? Chúng tôi đã đăng ký một trình xử lý cho TaskScheduler.UnobservedTaskException. Vấn đề là điều này có thể xảy ra sớm hơn nhiều hơn so với ngoại lệ không mong muốn gây ra.

Câu hỏi: Những tùy chọn tôi nên sử dụng nếu có:

  1. Tôi có nên quấn hành động của tôi Task s trong một try/catch và leo thang trong việc nắm bắt các ngoại lệ Tôi không mong đợi? Và nếu có, tôi nên làm gì để leo thang (ví dụ: tôi muốn làm cho sự kiện này xảy ra với sự kiện AppDomain.UnhandledException và kết thúc.

  2. Tôi có nên đính kèm () trên chủ đề ui (đây là ứng dụng Winforms)) mà rethrows các ngoại lệ nếu nó không phải là một ngoại lệ dự kiến ​​

  3. có một cách tiếp cận tiêu chuẩn tốt hơn hoặc nhiều

đây là những gì # 1 có thể trông giống như:?

var t1 = Task.Factory.StartNew(() => 
    { 
     try 
     { 
      string path = null; // Programming error. Should have been a valid string. Will cause System.ArgumentNullException below 
      using (FileStream fs = File.Create(path)) 
      { 

      } 
     } 
     catch (System.IO.IOException) { throw; } // Expected possible exception 
     catch (System.UnauthorizedAccessException) { throw; } 
     catch 
     { 
      // Anything caught here is not an expected exception and should be escalated. 
      // But how? 
     } 
    }); 

Đây là những gì # 2 có thể trông giống như:

TaskScheduler uiTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext(); 
var t1 = Task.Factory.StartNew(() => 
    { 
     string path = null; // Programming error. Should have been a valid string. Will cause System.ArgumentNullException below 
     using (FileStream fs = File.Create(path)) 
     { 

     } 
    }); 

t1.ContinueWith(t => 
    { 
     Exception ex = t.Exception; 
     if (ex is IOException || ex is UnauthorizedAccessException) // Expected exceptions (do nothing) 
      return; 

     throw ex; // Not expected (escalate by rethrowing) 

    }, CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, uiTaskScheduler); 

Trả lời

2

Gắn một sự tiếp nối cảm thấy như một cách tiếp cận tốt với tôi. Nếu bạn cảm thấy thoải mái với giả định rằng bạn sẽ không chặn luồng giao diện người dùng quá lâu vì các lý do khác, buộc việc tiếp tục chạy trên luồng giao diện người dùng có vẻ như là một lựa chọn rất hợp lý đối với tôi. Bằng cách đó bạn có thể thực hiện bất kỳ nhiệm vụ giao diện người dùng nào mà bạn cần cũng như một phần của việc tắt khẩn cấp.

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