在C#中创建可重用的方法超时类

时间:2009-04-27 12:53:13

标签: c# delegates

我正在尝试创建一个允许我调用具有指定时间的方法的类。我有实际的超时实现工作,但我很难成功地将它封装到一个类中。

我此时决定限制自己只使用5个Action代表来对需要0到4个参数的方法进行超时。出于这个问题的目的,我将使用Action的一个参数变体。

我的理想调用语法是这样的:

Action<int> a = new TimeoutAction(i => i + 1)
{
    Timeout = Timespan.FromSeconds(10)
}

或者这个:

Action<int> a = (x => x + 1).Timeout(Timespan.FromSeconds(10))

我几乎可以肯定第一个版本是不可能的,因为没有办法从委托继承。通过在Delegate类型上使用扩展方法,可以实现第二种方法。

最后一个回退是创建静态方法,这些方法接受适当的委托类型并返回具有相同签名但包含超时的委托。

有任何建议或想法吗?

4 个答案:

答案 0 :(得分:2)

你的最后一个建议是正确的方式:

  

最终的后备将是创造   接受的静态方法   适当的委托类型并返回一个   代表签名相同但是   包括超时。

换句话说:

public static Action<T> Timeout<T>(this Action<T> action, TimeSpan timeSpan);
public static Action<T1, T2> Timeout<T1, T2>(this Action<T1, T2> action, TimeSpan timeSpan);
public static Func<T, TResult> Timeout<T, TResult>(this Func<T, TResult> action, TimeSpan timeSpan);
public static Func<T1, T2, TResult> Timeout<T1, T2, TResult>(this Func<T1, T2, TResult> action, TimeSpan timeSpan);
/* snip the rest of the Action<...> and Func<...> overloads */

“为什么我不能只声明一个方法?”

您可以声明一个接受Delegate并返回Delegate的方法,但之后您将丢失委托类型信息(您的第二个示例将无法编译)。

不幸的是,以下示例无效C# - 您不能将Delegate用作类型参数约束:

public static TDelegate Timeout<TDelegate>(this TDelegate d, Timespan timespan) where TDelegate : Delegate;

答案 1 :(得分:0)

答案 2 :(得分:0)

here所述的Timed Lock方法怎么样?

答案 3 :(得分:-1)

嗯,一个lambda表达式不会“有一个类型”(任何你可以'点'或扩展方法),直到你把它包装起来。

new DelType(lambda)

Stat.Method(lambda)

或以其他方式提供上下文,所以我建议最终选项(静态方法):

Timeout.Action(lambda, timeoutVal)