I am developing a class library that has a bunch of method like "EnsureXXX". The idea of ββthese methods should be called up whenever the calling code requires something that may require initialization specific to the arguments. This is similar to the ASP.Net EnsureChildControls method, but with arguments as discriminators.
Example:
public static class SomeUtilityClass { public static void EnsureSomething(string arg1, int arg2, object arg3) {
Since such a template will be reused in several places and is called very often, I have to maintain performance as a goal. I must also have a thread safe method.
To this end, I wrote a small utility class:
public sealed class CallHelper { private static readonly HashSet<int> g_YetCalled = new HashSet<int>(); private static readonly object g_SyncRoot = new object(); public static void EnsureOnce(Type type, Action a, params object[] arguments) {
The consumption code is as follows:
public static class Program { static void Main() { SomeMethod("1", 1, 1); SomeMethod("2", 1, 1); SomeMethod("1", 1, 1); SomeMethod("1", 1, null); Console.ReadLine(); } static void SomeMethod(string arg1, int arg2, object arg3) { CallHelper.EnsureOnce(typeof(Program), ()=> { Console.WriteLine("SomeMethod called only once for {0}, {1} and {2}", arg1, arg2, arg3); }, arg1, arg2, arg3); } }
The output, as expected:
SomeMethod called only once for 1, 1 and 1 SomeMethod called only once for 2, 1 and 1 SomeMethod called only once for 1, 1 and
I have some questions related to this approach:
- I think I correctly locked the class to ensure thread safety, but am I right?
- Is a
HashSet<int> and my hash calculation method correct? I am particularly interested in the proper handling of null , and if I can delegate an Action delegate this way. - My methods currently only support static methods. How can I go to an instance of a compatible method (adding an instance as a discriminator) without memory leak?
- Is there a way to avoid passing all arguments manually to a utility method (just specifying an action) without exploring stacktrace (due to performance impact)? I am afraid that many errors have appeared due to missing arguments from an external method.
Thanks in advance