C#传递参数给Lambda表达式

3
在接下来的步骤中,我需要将 nextDB 传递到 Retry 中的 Lambda 表达式中:
Retry.Do(() => 
{
    string nextDB = dbList.Next();
    using (DataBaseProxy repo = new DataBaseProxy(nextDB))
    {
        return repo.DoSomething();
    }
});

我该怎么做呢?这是我的Retry类:

public static class Retry
{
    public static void Do(
        Action action,
        int retryCount = 3)
    {
        Do<object>(() =>
        {
            action();
            return null;
        }, retryCount);
    }

    public static T Do<T>(
        Func<T> action,
        int retryCount = 3)
    {
        var exceptions = new List<Exception>();

        for (int retry = 0; retry < retryCount; retry++)
        {
            try
            {
                return action();
            }
            catch (Exception ex)
            {
                exceptions.Add(ex);
            }
        }

        throw new AggregateException(exceptions);
    }
}

@DavidG - 我相信是这样的 - 我仍然希望它执行 Do 块中的代码 - 但我想能够将一个字符串传递给 Action。 - Robben_Ford_Fan_boy
@DavidG 不需要返回任何东西。是的 - 我只有一个参数。干杯 - Robben_Ford_Fan_boy
1个回答

6
我想你需要使用Action<T>。例如:
public static void Do<T>(
    Action<T> action,
    T param,
    int retryCount = 3)
{
    var exceptions = new List<Exception>();

    for (int retry = 0; retry < retryCount; retry++)
    {
        try
        {
            action(param);
            return;
        }
        catch (Exception ex)
        {
            exceptions.Add(ex);
        }
    }

    throw new AggregateException(exceptions);
}

您可以这样调用该函数:
Do(s => {
    Console.WriteLine(s);
}, "test", 3);

根据您的评论,似乎您想传入多个数据库并尝试按顺序执行每个,直到找到可用的为止。一个简单的选项是删除retryCount,并改为传入您的数组。
public static void Do<T>(
    Action<T> action,
    IEnumerable<T> items)
{
    var exceptions = new List<Exception>();

    foreach(var item in items)
    {
        try
        {
            action(item);
            return;
        }
        catch (Exception ex)
        {
            exceptions.Add(ex);
        }          
    }

    throw new AggregateException(exceptions);
}

现在你可以这样称呼它:

Do(s => {
    Console.WriteLine(s);
}, new[] { "db1", "db2", "db3" });

该死,我觉得这对我来说行不通,因为nextDB将超出范围,所以我无法传递它。 - Robben_Ford_Fan_boy
1
你是什么意思?你指的是哪个范围? - DavidG
1
所以您的意思是要传入3个不同的数据库,并在其中一个成功运行之前持续运行该方法? - DavidG
@就是这样。我想要一种通用的方法来尝试我的每个数据库。不幸的是,对于某些情况,我需要在重试方法中提供数据库名称。 - Robben_Ford_Fan_boy
1
那么像第二个版本这样的东西? - DavidG
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接