Creating a reusable method timeout class in C#

Creating a reusable method timeout class in C#

爱的那么颓废 发布于 2021-11-28 字数 1152 浏览 809 回复 4 原文

I am trying to create a class that lets me call methods with a specified timout. I have the actual timeout implementation working, but am having trouble encapsulating this into a class successfully.

I have decided at this time to limit myself to working with just the 5 Action delegates to put a timeout on methods that take 0 - 4 arguments. For the purposes of this question i will use the one argument variant of Action.

My Ideal calling syntax would be something like this:

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

or this:

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

I am almost sure that the first version isnt possible as there is no way to inherit from a delegate. The second may be possible by using an extension method on the Delegate type.

A final fallback would be to create static methods that take in the appropriate delegate type and return a Delegate with the same signature but with the timeouts included.

Any suggestions or ideas?

如果你对这篇文章有疑问,欢迎到本站 社区 发帖提问或使用手Q扫描下方二维码加群参与讨论,获取更多帮助。

扫码加入群聊

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

不再让梦枯萎 2022-06-07 4 楼

Well, a lambda expression won't "have a type" (anything you can 'dot' or extension method) until you wrap it in e.g.

new DelType(lambda)

or

Stat.Method(lambda)

or otherwise provide context, so I suggest the final option (static method):

Timeout.Action(lambda, timeoutVal)
朦胧时间 2022-06-07 3 楼

How about something like the approach to a Timed Lock as described here?

关于从前 2022-06-07 2 楼

Use AOP for that. Either PostSharp or DynamicProxy

抹茶夏天i‖ 2022-06-07 1 楼

Your last suggestion would be the right way:

A final fallback would be to create
static methods that take in the
appropriate delegate type and return a
Delegate with the same signature but
with the timeouts included.

In other words:

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 */

"Why can't I just declare one method?"

You could declare one method that accepts a Delegate and returns a Delegate, but then you'd lose the delegate type information (your second example wouldn't compile).

Unfortunately, the following example isn't valid C# -- you can't use Delegate as a type parameter constraint:

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