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ó:
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ệnAppDomain.UnhandledException
và kết thúc.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
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);