如何确保操作不会使整个应用程序崩溃?

我有一个应用程序执行一些额外的工作,例如清理旧日志、发送通知等。如果一项作业失败,我不希望整个应用程序停止工作并且不执行剩下的作业。


例如,


await SendUsersBirthdayEmailsAsync(); // <-- if something fails while trying to send birthday emails here, I don't want the app to stop working and not clean logs and so on...

await DeleteOutdatedLogsAsync();

await SendSystemNotificationsAsync();

你会推荐我搭配什么?


缥缈止盈
浏览 104回答 6
6回答

慕哥6287543

try-catch对可能失败的代码的每个部分使用块。根据您的需要,使用try-catch-finally块。在每个catch块上,根据需要记录异常。我使用 Nlog 进行日志记录,因此我建议对此进行研究。try{    //do work here}catch(Exception e){    //log exception here}//optionalfinally{    //do optional needed work here}像这样的东西:public bool SendUsersBirthdayEmailsAsync(){    try{        SendMail();    }    catch(Exception e){        LogException(e);    }    //optional    finally{        OptionalWork();    }       }编辑:关于避免使用通用异常您始终可以使用多个catch块来为每种类型的异常定义不同的行为。当您知道可能会出现什么样的异常时,这非常有用。例子:public bool SendUsersBirthdayEmailsAsync(){    try{        SendMail();    }    catch (ThreadAbortException tae)    {        LogException(tae);        //do something specific    }    catch (ThreadInterruptedException tie)    {        LogException(tie);        //do something specific    }    catch(Exception e){        LogException(e);    }    //optional    finally{        OptionalWork();    }       }编辑 2:异常处理的Microsoft 官方指南。try/catch在可能生成异常的代码周围使用块,您的代码可以从该异常中恢复。在catch块中,始终将异常从派生最多的到派生最少的排序。所有异常均源自Exception. 更多派生异常不会由catch前面有catch基本异常类子句的子句处理。当您的代码无法从异常中恢复时,不要捕获该异常。如果可能的话,启用调用堆栈上方的方法进行恢复。清理用using语句或finally块分配的资源。Preferusing语句在抛出异常时自动清理资源。使用finally块来清理未实现的资源IDisposable。finally即使抛出异常,子句中的代码也几乎总是会执行。

MMTTMM

您需要在每个函数中使用 Try-Catch,如下所示。try{&nbsp; &nbsp; //write your code}catch(Exception e){&nbsp; &nbsp; //your exception will be here}您可以为该异常生成一个日志文件。只需为您的日志文件做一件事。创建日志类和日志文件生成函数。在所有函数的 catch 区域中调用该函数。让您创建一个名为clsLog的 Log 类。和一个名为InsertLog(string exception, string functionname)的静态函数。在您的所有函数中使用此日志方法,如下所示。public void insertcity(){&nbsp;try&nbsp;{&nbsp; &nbsp;//Insert city programming&nbsp;}&nbsp;catch (exception ex)&nbsp;{&nbsp; &nbsp;clsLog.InsertLog(ex.Message,"insertCity");&nbsp; &nbsp;//do something else you want.&nbsp;}&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;}希望它会有所帮助。

不负相思意

未观察到的任务异常await SendUsersBirthdayEmailsAsync(); // uses TaskScheduler由于您正在使用 TaskScheduler,请查看TaskScheduler.UnobservedTaskException。当故障任务的未观察到的异常即将触发异常升级策略时发生,默认情况下,该策略将终止进程。

青春有我

正如这些方法的名称所示,这些方法是相互独立的,只需确保每个方法返回一个可等待的任务并将它们放入一个列表中即可。您使用的await建议,他们已经这样做了。在它周围放置一个 try-catch 并捕获 AggregateExeption。List<Task> tasks = new List<Task>();try{&nbsp; tasks.Add(SendUsersBirthdayEmailsAsync());&nbsp; tasks.Add(DeleteOutdatedLogsAsync());&nbsp; tasks.Add(SendSystemNotificationsAsync());&nbsp; Task.WhenAll(tasks); // waits for all tasks to finish}catch (Exception e){&nbsp; &nbsp;//Log e.ToString(); will give you all inner exceptions of the aggregate exception as well, incl. StackTraces, so expect possibly a lot of chars, wherever you log it.}这也可能会加快速度,因为它们现在是并行运行的。但由于它们似乎都在数据库上工作(很可能相同),因此由于调度开销,即使有的话,也可能不会太多。

天涯尽头无女友

我建议找出您从什么异常中async实际获得此异常并了解您可以在 main 上使用它Thread:MyTask().GetAwaiter().GetResult();这将允许您查看线程上实际异常的文本await。如果您不希望主线程返回到await您也可以使用的行:await&nbsp;SendUsersBirthdayEmailsAsync().ConfigureAwait(false);这只会在最近的空闲线程上继续您的任务。但需要说的是,这在Android上会导致异常,因为它对使用线程有一些限制。如果您不想浪费时间或不需要手动处理异常并修复它try,catch&nbsp;finally始终是一个选择。

眼眸繁星

Task<Task> task = (SendUsersBirthdayEmailsAsync()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .ContinueWith(x => Task.WhenAll(DeleteOutdatedLogsAsync(), SendSystemNotificationsAsync())));await await task;对于更一般的示例,提供了以下代码:class TaskTest{&nbsp; &nbsp; public async void Start()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; await (&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (await One().ContinueWith(x => Task.WhenAll(Two(), Three())))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .ContinueWith(x=> Four()));&nbsp; &nbsp; }&nbsp; &nbsp; private async Task One()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; await Task.Delay(5000);&nbsp; &nbsp; &nbsp; &nbsp; Console.WriteLine("1");&nbsp; &nbsp; &nbsp; &nbsp; throw new Exception();&nbsp; &nbsp; }&nbsp; &nbsp; private async Task Two()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; await Task.Delay(2000);&nbsp; &nbsp; &nbsp; &nbsp; Console.WriteLine("2");&nbsp; &nbsp; &nbsp; &nbsp; throw new Exception();&nbsp; &nbsp; }&nbsp; &nbsp; private async Task Three()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; await Task.Delay(3000);&nbsp; &nbsp; &nbsp; &nbsp; Console.WriteLine("3");&nbsp; &nbsp; &nbsp; &nbsp; throw new Exception();&nbsp; &nbsp; }&nbsp; &nbsp; private async Task Four()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; await Task.Delay(1000);&nbsp; &nbsp; &nbsp; &nbsp; Console.WriteLine("4");&nbsp; &nbsp; &nbsp; &nbsp; throw new Exception();&nbsp; &nbsp; }}运行此代码表明,在任务内引发异常不会停止整个程序。
打开App,查看更多内容
随时随地看视频慕课网APP