I come across this problem usually (especially when dealing with certain frameworks) where I would like once piece of code to execute once and only once however the provided method e.g (something like an onComplete function) that I wish to place this instruction in will in reality execute multiple times.
I am just wondering does anybody know of the best way that would get around this problem, one programmer friend of mine told me to use a flag (boolean) to check whether or not this code has already run but I feel like this is not a suitable solution and I would not like to introduce global variables for the sake of checking a condition once and only once.
Has anybody ever come across a problem like this before, I am wondering is there any good practice out there to keep in mind when dealing with code like this.
4
In C, I used to use function pointers for this. The first time the function was called, the initialization function was called. At the end of the initialization function, it changed the function pointer to point at the code that was to be called the rest of the time. There are various ways to do this in other languages, with various levels of efficiency.
2
these notes might be useful:
- You can create an idempotent function, which means that no matter how many times you call that method, you still get the same result.
- Using an
if
statement to check an external condition, and run the code only if that condition is not met. (Maybe another implementation of idempotency) - As you said, inject this dependency into your method. Your method is dependent upon an external state to tell it how many times it’s been executed. Thus if another manager (container) manage this for your method, things get easier.
1
The way it’s done in Grand Central Dispatch is to use a semaphore type called a “once token”. Your code would look something like this:
void do_something_once(once_token *token, void (*work)()) {
if(atomic_read(token) == 0) {
atomic_increment(token);
work();
}
}
void initialize() {/* the work */}
static once_token do_once = 0;
do_something_once(&do_once, initialize);
Where the details of atomically reading and incrementing the token depend on your platform.
1
A boolean flag indicating the method ran would be the right solution.
Not sure why you think this needs to be a global variable though – it can be declared outside the loop before it starts running.
If you do need to ensure that the method only ever runs once during the lifetime of the program run, there are several different ways to do this, depending on the language, but they do all essentially boil down to a global boolean (though in some languages that can be encapsulated).
For example in C#:
You can have the method live in a static class with a private static boolean – this would only be visible to the class itself and you can set it once the method executes the first time. Next time through, since the flag is set, you don’t execute the body of the method. Statics are global state, but as a private member, the flag is not visible to other classes.
1
In C# you might use a class like this:
public sealed class DoOnce
{
private Action _action;
public DoOnce(Action action)
{
_action = action;
}
public void Invoke()
{
var action = Interlocked.Exchange(ref _action, null);
action?.Invoke();
}
}
Then to use it:
var doOnce = new DoOnce(() => Console.WriteLine("Just the one time"));
doOnce.Invoke(); // prints
doOnce.Invoke(); // doesn't print
doOnce.Invoke(); // doesn't print
This will perform the action only one time, and is free from race conditions (it is thread safe).