1

我对 C# 比较陌生,也许你可以帮助我。

我有几个callServiceXY(param1, param2, ...)调用某个服务的方法。由于许多原因,这些服务调用可能会出错(我并不真正关心最终的原因)。所以基本上我需要总是用这样的东西包装它们 - 如果出现问题,让它们再次执行:

var i = 3;
while(i>0)
  try{
   call...()
  } catch{
   i--;
  }
  i=0;
}

我宁愿只写一次这段代码。我能以某种方式tryXtimes(int x, callService())让我执行未定义或匿名的方法吗?(我在脑海中想到了 Javascript……)?

4

3 回答 3

2

是的,这是可能的。C# 3.5 添加了对ActionFunc<T>类型的支持。Action 不会返回任何值,Func 将始终返回一个值。

您有几个不同的版本,它们也接受许多参数。以下控制台应用程序描述了如何执行此操作:

using System;

namespace Stackoverflow
{
    class Service
    {
        public int MyMethod() { return 42; }
        public void MyMethod(string param1, bool param2) { }

        public int MyMethod(object paramY) { return 42; }
    }

    class Program
    {
        static void ExecuteWithRetry(Action action)
        {
            try
            {
                action();
            }
            catch
            {
                action();
            }

        }

        static T ExecuteWithRetry<T>(Func<T> function)
        {
            try
            {
                return function();
            }
            catch
            {
                return function();
            }

        }

        static void Main(string[] args)
        { 
            Service s = new Service();
            ExecuteWithRetry(() => s.MyMethod("a", true));

            int a = ExecuteWithRetry(() => s.MyMethod(1));
            int b = ExecuteWithRetry(() => s.MyMethod(true));

        }
    }
}

如您所见, 有两个重载ExecuteWithRetry。一个返回 void,一个返回类型。您可以ExecuteWithRetry通过传递一个Action或一个来调用Func

--> 编辑:太棒了!只需一些额外的代码即可完成示例:

使用匿名函数/方法:

ExecuteWithRetry(() =>
{
   logger.Debug("test");
});

并带有更多参数(action,int)

方法头:

public static void ExecuteWithRetryX(Action a, int x)

方法调用:

ExecuteWithRetryX(() => { logger.Debug("test"); }, 2);
于 2012-12-29T10:50:31.087 回答
1

我会为此使用策略/工厂模式。这个答案https://stackoverflow.com/a/13641801/626442给出了使用带有链接的策略/工厂模式的示例。上述链接中的问题将为您提供另一种可以采用这种模式的示例。

这里有这些设计模式的很好的例子,下面是对策略模式工厂模式的详细介绍。最后两个链接中的前者还向您展示了如何将两者结合起来以执行您需要的操作。

我希望这有帮助。

于 2012-12-29T10:51:08.807 回答
0

尝试关注

    void CallServiceXY(params object []objects)
    {
        Console.WriteLine("a");
        throw new Exception("");
    }

    void Retry(int maxRetryCount, Action<object[]> action, params object[] obj)
    {
        int retryCount = 1;
        while ( retryCount <= maxRetryCount)
        {
            try
            {

            action(obj);
            return;
            }
            catch
            {
                retryCount++;
            }
        }
    }

    void Main()
    {
        Retry(2,CallServiceXY);
        Retry(2,CallServiceXY,"");
        Retry(2,CallServiceXY,"","");

    }

演示在这里

诀窍是Action<object[]>接受对象数组并在 Retry 方法中返回 void 和params关键字。
要返回非 void 值,请更改Action<object[]>Func<T, object[]>.

于 2012-12-29T11:15:05.467 回答