Robben_Ford_Fan_boy
Robben_Ford_Fan_boy

Reputation: 8738

C# Pass Parameter to Lambda

In the following, I need to pass nextDB to the Lambda expression in Retry:

Retry.Do(() => 
{
    string nextDB = dbList.Next();
    using (DataBaseProxy repo = new DataBaseProxy(nextDB))
    {
        return repo.DoSomething();
    }
});

How do I do that? Here is my Retry class:

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);
    }
}

Upvotes: 3

Views: 2685

Answers (1)

DavidG
DavidG

Reputation: 119186

I think you want to be using Action<T> here. For example:

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);
}

You would call this function like this:

Do(s => {
    Console.WriteLine(s);
}, "test", 3);

Based on your comments, it seems that you want to pass in multiple databases and try each one in succession until you find one that works. One simple option would be to remove to retryCount and instead pass in your array.

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);
}

And now you call it something like this:

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

Upvotes: 6

Related Questions