It depends on whether or not you care about the past or future state of the property in question.
To try to simplify the semantics, realize that there are a few scenarios that make the IsXXX form debatable and some very common scenarios where the IsXXX form is the only useful one.
Below is the 'truth table' for Thread.IsAlive() based on possible states of the thread over time. Forget about why a thread might flip flop states, we need to focus on the language used.
Scenarios of possible thread states over time:
Past Present Future
===== ======= =======
1. alive alive alive
2. alive alive dead
3. alive dead dead
4. dead dead dead
5. dead dead alive
6. dead alive alive
7. dead alive dead
8. alive dead alive
Note: I talk about the Future state below for consistency. Knowing whether a thread will die is very likely unknowable as a subset of The Halting Problem)
When we interrogate an object by calling a method, there is a common assumption "Is this thread alive, at the time I asked? For these cases, the answer in the "Present" column is all we care about and using the IsXXX form works fine.
Scenarios #1(always alive) and #4(always dead) are the simplest and most common. The answer to IsAlive()
will not change between calls. The battle over language that comes up is due to the other 6 cases where the result of calling IsAlive()
depends on when it is called.
Scenarios #2(will die) and #3(has died) transitions from alive to dead.
Scenarios #5(will start) and #6(has started) transitions from dead to alive.
For these four (2, 3, 5, 6) the answer to IsAlive()
is not constant. The question becomes, do I care about the Present state, IsAlive()
, or am I interested in the Past/Future state, WasAlive()
and WillBeAlive()
? Unless you can predict the future, the WillBeAlive()
call becomes meaningless for all but the most specific designs.
When dealing with a thread pool, we might need to restart threads that are in the 'dead' state to service connect requests and it doesn't matter whether they were ever alive, just that they are currently dead. In this case we might actually want to use WasDead()
. Of course we should try to guarantee we don't restart a thread that was just restarted but that is a design problem, not a semantic one. Assuming that no one else can restart the thread, it doesn't matter much whether we use IsAlive() == false
or WasDead() == true
.
Now for the last two scenarios. Scenario #7(was dead, is alive, will be dead) is practically the same as #6. Do you know when in the future it will die? In 10 seconds, 10 minutes, 10 hours? Are you going to wait before deciding what to do. No, you only care about the current (Present) state. We're talking about naming here, not multi-threaded design.
Scenario #8(was alive, is dead, will be alive), is practically the same as #3. If you are reusing threads, then they can cycle through the alive/dead states several times. Worrying about the difference between #3 and #8 goes back to the Halting Problem and so can be disregarded.
IsAlive()
should work for all cases. IsAlive() == false
works (for #5 and #6) instead of adding WasAlive()
.