久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

任務發生異常時,根據用戶輸入多次重試任務

Retry a task multiple times based on user input in case of an exception in task(任務發生異常時,根據用戶輸入多次重試任務)
本文介紹了任務發生異常時,根據用戶輸入多次重試任務的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

問題描述

我的應用程序中的所有服務調用都是作為任務實現的.當某個任務出現故障時,我需要向用戶顯示一個對話框來重試上次失敗的操作.如果用戶選擇重試,程序應該重試該任務,否則程序的執行應該在記錄異常后繼續.任何人對如何實現這個功能有一個高層次的想法?

All the service calls in my application are implemented as tasks.When ever a task is faulted ,I need to present the user with a dialog box to retry the last operation failed.If the user chooses retry the program should retry the task ,else the execution of the program should continue after logging the exception.Any one has got a high level idea on how to implement this functionality ?

推薦答案

UPDATE 5/2017

C# 6 異常過濾器使 catch 子句更加簡單:

C# 6 exception filters make the catch clause a lot simpler :

    private static async Task<T> Retry<T>(Func<T> func, int retryCount)
    {
        while (true)
        {
            try
            {
                var result = await Task.Run(func);
                return result;
            }
            catch when (retryCount-- > 0){}
        }
    }

還有一個遞歸版本:

    private static async Task<T> Retry<T>(Func<T> func, int retryCount)
    {
        try
        {
            var result = await Task.Run(func);
            return result;
        }
        catch when (retryCount-- > 0){}
        return await Retry(func, retryCount);
    }

原創

編寫重試函數的方法有很多種:您可以使用遞歸或任務迭代.不久前,希臘 .NET 用戶組中有一個 討論做到這一點的不同方法.
如果您使用 F#,您還可以使用 Async 構造.不幸的是,您至少不能在 Async CTP 中使用 async/await 構造,因為編譯器生成的代碼不喜歡多個等待或可能在 catch 塊中重新拋出.

There are many ways to code a Retry function: you can use recursion or task iteration. There was a discussion in the Greek .NET User group a while back on the different ways to do exactly this.
If you are using F# you can also use Async constructs. Unfortunately, you can't use the async/await constructs at least in the Async CTP, because the code generated by the compiler doesn't like multiple awaits or possible rethrows in catch blocks.

遞歸版本可能是在 C# 中構建重試的最簡單方法.以下版本不使用 Unwrap 并在重試之前添加可選延遲:

The recursive version is perhaps the simplest way to build a Retry in C#. The following version doesn't use Unwrap and adds an optional delay before retries :

private static Task<T> Retry<T>(Func<T> func, int retryCount, int delay, TaskCompletionSource<T> tcs = null)
    {
        if (tcs == null)
            tcs = new TaskCompletionSource<T>();
        Task.Factory.StartNew(func).ContinueWith(_original =>
        {
            if (_original.IsFaulted)
            {
                if (retryCount == 0)
                    tcs.SetException(_original.Exception.InnerExceptions);
                else
                    Task.Factory.StartNewDelayed(delay).ContinueWith(t =>
                    {
                        Retry(func, retryCount - 1, delay,tcs);
                    });
            }
            else
                tcs.SetResult(_original.Result);
        });
        return tcs.Task;
    } 

StartNewDelayed 函數來自ParallelExtensionsExtras 采樣并使用計時器觸發超時發生時的TaskCompletionSource.

The StartNewDelayed function comes from the ParallelExtensionsExtras samples and uses a timer to trigger a TaskCompletionSource when the timeout occurs.

F# 版本要簡單得多:

The F# version is a lot simpler:

let retry (asyncComputation : Async<'T>) (retryCount : int) : Async<'T> = 
let rec retry' retryCount = 
    async {
        try
            let! result = asyncComputation  
            return result
        with exn ->
            if retryCount = 0 then
                return raise exn
            else
                return! retry' (retryCount - 1)
    }
retry' retryCount

不幸的是,在 C# 中使用 Async CTP 中的 async/await 編寫類似的東西是不可能的,因為編譯器不喜歡 catch 塊中的 await 語句.以下嘗試也靜默失敗,因為運行時不喜歡在異常后遇到等待:

Unfortunatley, it isn't possible to write something similar in C# using async/await from the Async CTP because the compiler doesn't like await statements inside a catch block. The following attempt also fails silenty, because the runtime doesn't like encountering an await after an exception:

private static async Task<T> Retry<T>(Func<T> func, int retryCount)
    {
        while (true)
        {
            try
            {
                var result = await TaskEx.Run(func);
                return result;
            }
            catch 
            {
                if (retryCount == 0)
                    throw;
                retryCount--;
            }
        }
    }

關于詢問用戶,可以修改Retry,調用一個詢問用戶并通過TaskCompletionSource返回任務的函數,在用戶回答時觸發下一步,例如:

As for asking the user, you can modify Retry to call a function that asks the user and returns a task through a TaskCompletionSource to trigger the next step when the user answers, eg:

 private static Task<bool> AskUser()
    {
        var tcs = new TaskCompletionSource<bool>();
        Task.Factory.StartNew(() =>
        {
            Console.WriteLine(@"Error Occured, continue? YN");
            var response = Console.ReadKey();
            tcs.SetResult(response.KeyChar=='y');

        });
        return tcs.Task;
    }

    private static Task<T> RetryAsk<T>(Func<T> func, int retryCount,  TaskCompletionSource<T> tcs = null)
    {
        if (tcs == null)
            tcs = new TaskCompletionSource<T>();
        Task.Factory.StartNew(func).ContinueWith(_original =>
        {
            if (_original.IsFaulted)
            {
                if (retryCount == 0)
                    tcs.SetException(_original.Exception.InnerExceptions);
                else
                    AskUser().ContinueWith(t =>
                    {
                        if (t.Result)
                            RetryAsk(func, retryCount - 1, tcs);
                    });
            }
            else
                tcs.SetResult(_original.Result);
        });
        return tcs.Task;
    } 

通過所有的延續,您可以看到為什么異步版本的 Retry 如此受歡迎.

With all the continuations, you can see why an async version of Retry is so desirable.

更新:

在 Visual Studio 2012 Beta 中,以下兩個版本有效:

In Visual Studio 2012 Beta the following two versions work:

帶有while循環的版本:

A version with a while loop:

    private static async Task<T> Retry<T>(Func<T> func, int retryCount)
    {
        while (true)
        {
            try
            {
                var result = await Task.Run(func);
                return result;
            }
            catch
            {
                if (retryCount == 0)
                    throw;
                retryCount--;
            }
        }
    }

還有一個遞歸版本:

    private static async Task<T> Retry<T>(Func<T> func, int retryCount)
    {
        try
        {
            var result = await Task.Run(func);
            return result;
        }
        catch
        {
            if (retryCount == 0)
                throw;
        }
        return await Retry(func, --retryCount);
    }

這篇關于任務發生異常時,根據用戶輸入多次重試任務的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!

【網站聲明】本站部分內容來源于互聯網,旨在幫助大家更快的解決問題,如果有圖片或者內容侵犯了您的權益,請聯系我們刪除處理,感謝您的支持!

相關文檔推薦

Is there a C# library that will perform the Excel NORMINV function?(是否有執行 Excel NORMINV 函數的 C# 庫?)
Select x random elements from a weighted list in C# (without replacement)(從 C# 中的加權列表中選擇 x 個隨機元素(無需替換))
Create a summary description of a schedule given a list of shifts(給定輪班列表,創建時間表的摘要描述)
C# Normal Random Number(C# 普通隨機數)
Standard deviation of generic list?(通用列表的標準偏差?)
AsyncCTP: Creating a class that is IAwaitable(AsyncCTP:創建一個 IAwaitable 的類)
主站蜘蛛池模板: 国产精品综合视频 | 97热在线 | 男插女下体视频 | 久热精品视频 | aaaaaaa片毛片免费观看 | a级黄色网 | 精品久久久久久亚洲精品 | 91精品久久久久久久久久入口 | 欧美视频成人 | 日韩一区二区不卡 | 自拍偷拍第一页 | 国产黄色网址在线观看 | 欧美日韩综合一区 | 国产精品久久国产精品 | 一区二区三区视频 | 国产成人在线一区二区 | 成人a视频 | 亚洲一区在线日韩在线深爱 | 在线免费看黄 | 亚洲午夜精品一区二区三区他趣 | 国产超碰人人爽人人做人人爱 | 激情五月婷婷在线 | 四虎最新视频 | 国产一区二区观看 | 日本不卡一区二区三区在线观看 | 久久久久亚洲精品国产 | 日韩欧美在线观看一区 | 91热在线| 日本又色又爽又黄又高潮 | 国产免费xxx | 久久久亚洲精品视频 | 99视频免费在线 | 日韩欧美在线不卡 | 天天综合天天 | 欧美成人精品一区二区三区 | 草草草影院 | 亚洲视频国产视频 | 美国av片在线观看 | 日本一区二区三区四区 | 久久久久久综合 | 最新免费av网站 |