亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何確保操作不會使整個應用程序崩潰?

如何確保操作不會使整個應用程序崩潰?

C#
縹緲止盈 2023-09-16 15:01:56
我有一個應用程序執行一些額外的工作,例如清理舊日志、發送通知等。如果一項作業失敗,我不希望整個應用程序停止工作并且不執行剩下的作業。例如,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();你會推薦我搭配什么?
查看完整描述

6 回答

?
慕哥6287543

TA貢獻1831條經驗 獲得超10個贊

try-catch對可能失敗的代碼的每個部分使用塊。

根據您的需要,使用try-catch-finally塊。


在每個catch塊上,根據需要記錄異常。我使用 Nlog 進行日志記錄,因此我建議對此進行研究。


try{

? ? //do work here

}

catch(Exception e){

? ? //log exception here

}

//optional

finally{

? ? //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即使拋出異常,子句中的代碼也幾乎總是會執行。


查看完整回答
反對 回復 2023-09-16
?
MMTTMM

TA貢獻1869條經驗 獲得超4個贊

您需要在每個函數中使用 Try-Catch,如下所示。


try{

    //write your code

}

catch(Exception e){

    //your exception will be here

}

您可以為該異常生成一個日志文件。只需為您的日志文件做一件事。創建日志類和日志文件生成函數。在所有函數的 catch 區域中調用該函數。


讓您創建一個名為clsLog的 Log 類。和一個名為InsertLog(string exception, string functionname)的靜態函數。


在您的所有函數中使用此日志方法,如下所示。


public void insertcity()

{

 try

 {

   //Insert city programming

 }

 catch (exception ex)

 {

   clsLog.InsertLog(ex.Message,"insertCity");

   //do something else you want.

 }        

}

希望它會有所幫助。


查看完整回答
反對 回復 2023-09-16
?
不負相思意

TA貢獻1777條經驗 獲得超10個贊

未觀察到的任務異常

await?SendUsersBirthdayEmailsAsync();?//?uses?TaskScheduler

由于您正在使用 TaskScheduler,請查看TaskScheduler.UnobservedTaskException。

當故障任務的未觀察到的異常即將觸發異常升級策略時發生,默認情況下,該策略將終止進程。


查看完整回答
反對 回復 2023-09-16
?
青春有我

TA貢獻1784條經驗 獲得超8個贊

正如這些方法的名稱所示,這些方法是相互獨立的,只需確保每個方法返回一個可等待的任務并將它們放入一個列表中即可。您使用的await建議,他們已經這樣做了。


在它周圍放置一個 try-catch 并捕獲 AggregateExeption。


List<Task> tasks = new List<Task>();

try

{

  tasks.Add(SendUsersBirthdayEmailsAsync());

  tasks.Add(DeleteOutdatedLogsAsync());

  tasks.Add(SendSystemNotificationsAsync());


  Task.WhenAll(tasks); // waits for all tasks to finish

}

catch (Exception e)

{

   //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.

}

這也可能會加快速度,因為它們現在是并行運行的。但由于它們似乎都在數據庫上工作(很可能相同),因此由于調度開銷,即使有的話,也可能不會太多。


查看完整回答
反對 回復 2023-09-16
?
天涯盡頭無女友

TA貢獻1831條經驗 獲得超9個贊

我建議找出您從什么異常中async實際獲得此異常并了解您可以在 main 上使用它Thread

MyTask().GetAwaiter().GetResult();

這將允許您查看線程上實際異常的文本await。


如果您不希望主線程返回到await您也可以使用的行:

await SendUsersBirthdayEmailsAsync().ConfigureAwait(false);

這只會在最近的空閑線程上繼續您的任務。

但需要說的是,這在Android上會導致異常,因為它對使用線程有一些限制。


如果您不想浪費時間或不需要手動處理異常并修復它try,catch finally始終是一個選擇。


查看完整回答
反對 回復 2023-09-16
?
眼眸繁星

TA貢獻1873條經驗 獲得超9個贊

Task<Task> task = (SendUsersBirthdayEmailsAsync()

            .ContinueWith(x => Task.WhenAll(DeleteOutdatedLogsAsync(), SendSystemNotificationsAsync())));

await await task;

對于更一般的示例,提供了以下代碼:


class TaskTest

{

    public async void Start()

    {


        await (

            (await One().ContinueWith(x => Task.WhenAll(Two(), Three())))

            .ContinueWith(x=> Four()));

    }


    private async Task One()

    {

        await Task.Delay(5000);

        Console.WriteLine("1");

        throw new Exception();

    }


    private async Task Two()

    {

        await Task.Delay(2000);

        Console.WriteLine("2");

        throw new Exception();


    }

    private async Task Three()

    {

        await Task.Delay(3000);

        Console.WriteLine("3");

        throw new Exception();

    }


    private async Task Four()

    {

        await Task.Delay(1000);

        Console.WriteLine("4");

        throw new Exception();

    }

}

運行此代碼表明,在任務內引發異常不會停止整個程序。


查看完整回答
反對 回復 2023-09-16
  • 6 回答
  • 0 關注
  • 190 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號