【问题标题】:How to retry a task in .NET 4.0? [closed]如何在 .NET 4.0 中重试任务? [关闭]
【发布时间】:2013-03-18 04:51:40
【问题描述】:

accepted answer to earlier 问题“在任务中出现异常时根据用户输入多次重试任务”提供了 C# 5.0 中的代码

我不熟悉 .NET 异步,使用 .NET 4.0 的 await 构造很难将 C# 4.0 中的代码组合在一起。其他答案也包含谜题

您能否提供一个完整的 C# 4.0 源代码,即示例,如何在 C# 中重试任务,包括处理异常并允许取消而不重试?

【问题讨论】:

  • -1 您在跟进中的态度而没有改善您的问题以回应其中明显的弱点加上阅读这个毫无价值的问答浪费了我的几分钟时间设定让我希望这个问题消失。您能否跟进您到目前为止所获得的内容和/或缺失的部分是什么,或者请删除问题。或接受答案

标签: c# .net c#-4.0 concurrency task-parallel-library


【解决方案1】:

如果我正确理解了您的问题,您要求的解决方案类似于this question 中建议的解决方案。在这里,Jon Skeet 给出了用于一般操作的 Retry 方法的实现。此外,您要求包含 execption 处理可以取消操作而不重试的可能性。在这种情况下,Jon 还提到了合并一个 ShouldRetry(Exception) 方法的可能性,您可以使用该方法来确定重试是否合理。因此,我在 Jon 的原始代码中加入了一些示例代码:

public static Func<T> Retry(Func<T> original, int retryCount)
{
    return () =>
    {
        while (true)
        {
            try
            {
                return original();
            }
            catch (Exception e)
            {
                if (retryCount == 0 || !ShouldRetry(e))
                {
                    throw;
                }

                // TODO: Logging
                retryCount--;
            }
        }
   };
}

public static bool ShouldRetry(Exception e) {
    return (e is MySpecialExceptionThatAllowsForARetry)
}

这是否阐明了另一个问题的答案?

编辑:其他人已经正确指出我的代码可以在考虑的情况下简化/专门化。上面的代码将Func 包装成一个retriable(或者更确切地说是retryingFunc。适合问题的更简单的形式是

public static T Retry(Task<T> original, int retryCount)
{
    while (true)
    {
        try
        {
            return original();
        }
        catch (Exception e)
        {
            if (retryCount == 0 || !ShouldRetry(e))
            {
                throw;
            }

            // TODO: Logging
            retryCount--;
        }
    }
}

【讨论】:

  • 你刚刚复制粘贴了existing answer的代码。我看到了,我很难把完整的示例代码放在一起。
  • @fulproof - 如果您询问有关您在使用此示例时遇到的困难的具体问题,也许会有所帮助。这对我来说似乎相当清楚。
  • @fulproof:是的,我大部分复制并粘贴了另一个问题的答案(即,您在问题中未提及的问题),但也请考虑我所做的细微改变。此外,我试图找到一个使用普通 .NET 4.0 代码的答案(它,afaik,确实如此),但似乎理解问题似乎在别处。那么,如果您能听从 Andrew 的建议来找出这些问题,会有所帮助吗?
  • @bigge,我很欣赏一个示例,即我可以编译和运行的完整代码
  • Returning Func 在这里看起来没有必要。你可以在里面运行循环。
【解决方案2】:

好吧,如果将Jon Skeet's answeroriginal answer 一起引用,那么它应该指定:

private static Task<T> CreateTaskWithRetry<T>(Func<T> action, int retryCount)

代替:

public static Func<T> Retry(Func<T> original, int retryCount)

【讨论】:

  • 这个想法是您只需在Task.Run 的答案中提供方法,而不是提供一些其他功能并尝试重试该任务。方法本身不需要将自己移动到线程池线程中。
  • 不用了,谢谢。你似乎是一个相当不讲理和要求很高的人,除了为你做你全部工作的人之外,什么都不愿意接受。当有人花时间帮助你,为你的问题提供大部分解决方案时,虽然是笼统的,但你根本不接受。
  • @Servy,你能把你的评论作为答案在这里或那里吗?我不明白!当我特别要求将那里的答案和代码迁移到 .NET 4.0 时,您是否指的是 .NET 4.5 中不存在的 .NET 4.5 Task.Run()
  • 如果您需要 4.0 解决方案,您可以使用 Task.Factory.StartNew,因为这就是 Run 所做的一切。我认为您可以自行推断。
  • 我不同意。花几秒钟对问题进行一些琐碎的研究并自己找到解决方案所花费的时间和精力要比在没有时间或没有时间的情况下花时间要求其他人为您完成工作所花费的时间和精力要少得多自己努力。这最终会消耗更多自己的时间,而当你加上其他人的时间时,效率显然会更差。现在,对于一个您在 20 秒的 Google 搜索中无法回答的更复杂的问题,提问很有可能会更有效率。
猜你喜欢
  • 2023-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-15
  • 1970-01-01
相关资源
最近更新 更多