C# 停止异步lambda向上传播调用堆栈的异常
下面的代码有一个TaskMonitor类,它是Stephen Cleary的修改版本。Worker类使用TaskMonitor类异步运行Worker.CheckStatus Worker.CheckStatus通常会引发异常(例如数据库连接问题)。我希望TaskMonitor.Monitor阻止该异常到达Program.Main,并通过Exception和InnerException属性公开它。TaskMonitor.Monitor中的catch块被命中,但未按预期吞下异常;异常被传递到Program.Main并使应用程序崩溃。如何停止TaskMonitor.Monitor中的异常C# 停止异步lambda向上传播调用堆栈的异常,c#,exception,async-await,C#,Exception,Async Await,下面的代码有一个TaskMonitor类,它是Stephen Cleary的修改版本。Worker类使用TaskMonitor类异步运行Worker.CheckStatus Worker.CheckStatus通常会引发异常(例如数据库连接问题)。我希望TaskMonitor.Monitor阻止该异常到达Program.Main,并通过Exception和InnerException属性公开它。TaskMonitor.Monitor中的catch块被命中,但未按预期吞下异常;异常被传递到Prog
public sealed class TaskMonitor {
// Based on Stephen Cleary's NotifyTaskCompletion:
// https://github.com/StephenCleary/Mvvm/blob/master/future/Nito.Mvvm.Async/NotifyTask.cs
public TaskMonitor(Task task = null) {
Task = task;
}
public AggregateException Exception {
get {
return Task?.Exception;
}
}
public Exception InnerException {
get {
return Exception?.InnerException;
}
}
public bool IsCompleted {
get {
return Task != null && Task.IsCompleted;
}
}
public bool IsRunning {
get {
return Task != null && !Task.IsCompleted;
}
}
private async Task Monitor(Task task) {
try {
if(task != null) {
await task;
}
}
catch {
// Drop exceptions
}
finally {
// do other stuff here like raise PropertyChanged
}
}
private Task _task;
public Task Task {
get => _task;
set {
if(Task != value) {
_task = value;
_ = Monitor(Task);
}
}
}
}
public class Worker {
public Worker() {
CheckStatusMonitor = new TaskMonitor();
}
public void CheckStatus() {
if(!CheckStatusMonitor.IsRunning) {
CheckStatusMonitor.Task = Task.Run(async () => {
var newStatus = WorkerStatus.Unknown;
try {
// Force a database connection failure
var cn = new SqlConnection();
await cn.OpenAsync();
newStatus = WorkerStatus.Good;
}
catch(Exception ex) {
newStatus = WorkerStatus.Error;
throw ex;
}
finally {
Status = newStatus;
}
});
}
}
public TaskMonitor CheckStatusMonitor { get; private set; }
public WorkerStatus Status { get; private set; }
}
public enum WorkerStatus {
Unknown,
Error,
Good,
}
class Program {
public static async Task Main() {
var worker = new Worker();
worker.CheckStatus();
await worker.CheckStatusMonitor.Task;
Debug.WriteLine(worker.CheckStatusMonitor.ErrorMessage);
}
}
TaskMonitor.Monitor中的catch块被命中,但未按预期吞下异常;异常被传递到Program.Main并使应用程序崩溃。如何停止TaskMonitor.Monitor中的异常
public sealed class TaskMonitor {
// Based on Stephen Cleary's NotifyTaskCompletion:
// https://github.com/StephenCleary/Mvvm/blob/master/future/Nito.Mvvm.Async/NotifyTask.cs
public TaskMonitor(Task task = null) {
Task = task;
}
public AggregateException Exception {
get {
return Task?.Exception;
}
}
public Exception InnerException {
get {
return Exception?.InnerException;
}
}
public bool IsCompleted {
get {
return Task != null && Task.IsCompleted;
}
}
public bool IsRunning {
get {
return Task != null && !Task.IsCompleted;
}
}
private async Task Monitor(Task task) {
try {
if(task != null) {
await task;
}
}
catch {
// Drop exceptions
}
finally {
// do other stuff here like raise PropertyChanged
}
}
private Task _task;
public Task Task {
get => _task;
set {
if(Task != value) {
_task = value;
_ = Monitor(Task);
}
}
}
}
public class Worker {
public Worker() {
CheckStatusMonitor = new TaskMonitor();
}
public void CheckStatus() {
if(!CheckStatusMonitor.IsRunning) {
CheckStatusMonitor.Task = Task.Run(async () => {
var newStatus = WorkerStatus.Unknown;
try {
// Force a database connection failure
var cn = new SqlConnection();
await cn.OpenAsync();
newStatus = WorkerStatus.Good;
}
catch(Exception ex) {
newStatus = WorkerStatus.Error;
throw ex;
}
finally {
Status = newStatus;
}
});
}
}
public TaskMonitor CheckStatusMonitor { get; private set; }
public WorkerStatus Status { get; private set; }
}
public enum WorkerStatus {
Unknown,
Error,
Good,
}
class Program {
public static async Task Main() {
var worker = new Worker();
worker.CheckStatus();
await worker.CheckStatusMonitor.Task;
Debug.WriteLine(worker.CheckStatusMonitor.ErrorMessage);
}
}
在Main
中,您的代码正在执行wait worker.CheckStatusMonitor.Task代码>从TaskMonitor返回的任务。任务
是任务。从工作者运行
任务。检查状态
,而不是从TaskMonitor.Monitor
返回的任务
如果要忽略异常,则需要等待正确的任务:
public Task Task {
get => _task;
set {
_task = Monitor(value);
}
}
请注意,if(Task!=value)
已被删除,因为这显然不起作用,因为任务正在被替换
TaskMonitor.Monitor中的catch块被命中,但未按预期吞下异常;异常被传递到Program.Main并使应用程序崩溃。如何停止TaskMonitor.Monitor中的异常
public sealed class TaskMonitor {
// Based on Stephen Cleary's NotifyTaskCompletion:
// https://github.com/StephenCleary/Mvvm/blob/master/future/Nito.Mvvm.Async/NotifyTask.cs
public TaskMonitor(Task task = null) {
Task = task;
}
public AggregateException Exception {
get {
return Task?.Exception;
}
}
public Exception InnerException {
get {
return Exception?.InnerException;
}
}
public bool IsCompleted {
get {
return Task != null && Task.IsCompleted;
}
}
public bool IsRunning {
get {
return Task != null && !Task.IsCompleted;
}
}
private async Task Monitor(Task task) {
try {
if(task != null) {
await task;
}
}
catch {
// Drop exceptions
}
finally {
// do other stuff here like raise PropertyChanged
}
}
private Task _task;
public Task Task {
get => _task;
set {
if(Task != value) {
_task = value;
_ = Monitor(Task);
}
}
}
}
public class Worker {
public Worker() {
CheckStatusMonitor = new TaskMonitor();
}
public void CheckStatus() {
if(!CheckStatusMonitor.IsRunning) {
CheckStatusMonitor.Task = Task.Run(async () => {
var newStatus = WorkerStatus.Unknown;
try {
// Force a database connection failure
var cn = new SqlConnection();
await cn.OpenAsync();
newStatus = WorkerStatus.Good;
}
catch(Exception ex) {
newStatus = WorkerStatus.Error;
throw ex;
}
finally {
Status = newStatus;
}
});
}
}
public TaskMonitor CheckStatusMonitor { get; private set; }
public WorkerStatus Status { get; private set; }
}
public enum WorkerStatus {
Unknown,
Error,
Good,
}
class Program {
public static async Task Main() {
var worker = new Worker();
worker.CheckStatus();
await worker.CheckStatusMonitor.Task;
Debug.WriteLine(worker.CheckStatusMonitor.ErrorMessage);
}
}
在Main
中,您的代码正在执行wait worker.CheckStatusMonitor.Task代码>从TaskMonitor返回的任务。任务
是任务。从工作者运行
任务。检查状态
,而不是从TaskMonitor.Monitor
返回的任务
如果要忽略异常,则需要等待正确的任务:
public Task Task {
get => _task;
set {
_task = Monitor(value);
}
}
请注意,如果(Task!=value)
被删除,因为这显然不起作用,因为任务正在被替换。您将\u Task
设置为从任务返回的任务。运行,而不是从监视器返回的任务。然后在await worker.CheckStatusMonitor.Task中等待
您将\u任务
设置为从任务返回的任务
。运行
,而不是从监视器
返回的任务
。然后在await worker.CheckStatusMonitor.Task中等待代码>我非常确定CheckStatus中的Task.Run调用以某种方式作为异步void运行,因此我忽略了代码正在等待错误的任务。为了解决这个问题,我添加了TaskMonitor.MonitorTask属性(比如NotifyTask.TaskCompleted),并修改了其他TaskMonitor属性以引用相应的任务。谢谢你的帮助!我非常确定CheckStatus中的Task.Run调用以某种方式作为异步void运行,因此我忽略了代码正在等待错误的任务。为了解决这个问题,我添加了TaskMonitor.MonitorTask属性(比如NotifyTask.TaskCompleted),并修改了其他TaskMonitor属性以引用相应的任务。谢谢你的帮助!