Click here to Skip to main content
15,888,968 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have some odd behaviour in code that is seemingly so simple I have run out of places to look for the bug.

In the class below, the function RunStepNormally() is called. Good so far.

I then call SomeClass.InitiateTimeSeek(), which is confirmed by a breakpoint being hit. Still good so far.

The problem comes next cycle. In RunStep(), the value of _runningRealTime is true, even though it was explicitly set to false in InitiateTimeSeek().

If I change the initialisation value of _runningRealTime to false then it remains at false. In other words, in RunStep(), I always see whatever value _runningRealTime is initialised to and never see anything different.

public abstract class SomeClass<T>
{
	public void RunStep()
	{
		if( _runningRealTime )
			RunStepNormally();
		else
			RunStepTimeSkipActive();
	}

	public static void InitiateTimeSeek()
	{
		_runningRealTime = false;
	}

	public static void CancelTimeSeek()
	{
		_runningRealTime = true;
	}

	public void RunStepNormally() {}

	public void RunStepTimeSkipActive() {}


	private static bool _runningRealTime = true;
}


Because this code is so simple, I get the feeling I must be missing something really dumb. Does anyone have any suggestions what may be happening?

What I have tried:

My first thought was that new instances of the class were being created repeatedly, but a breakpoint in the constructor (not shown) is hit only once, as I would expect.
Posted
Updated 10-Aug-20 0:03am
v2

Your code will not compile for me:
Error	CS0127	Since 'FrmMain.SomeClass.RunStep()' returns void, a return keyword must not be followed by an object expression	OneOffJobs	D:\Documents\AA Backed Up\My Projects\OneOffJobs\OneOffJobs\FrmMain.cs	113	Active
That's running with .NET 4.72 on VS2019

So ... if the code won't compile, then what runs may not match that code.
Either you cut down the code sample too severely to show the problem, or your actual code is running against an outdated class.
 
Share this answer
 
Comments
Patrick Skelton 10-Aug-20 5:40am    
So sorry! I did indeed cut the code clumsily. I have corrected it and added a couple of lines to make it more complete. I've also removed the 'async' bits because they were just confusing things. I should also point out that this class is an abstract generic class, though I struggle to see why this should be relevant (a view I may end up retracting, when I have exhausted all other possibilities).
OriginalGriff 10-Aug-20 6:14am    
That's simple: each generic type gets its own static variable, they don't interact. (Which makes sense if you think about it: A List<int> is not the same class as a List<string> and they can't be cast to each other, so why would they share anything?)

The easiest solution is to create another - non generic - abstract base class from which SomeClass derives and have that define the static variable.
Your class is generic. You will have a separate copy of the static fields for each generic type parameter. If you call SomeClass<Foo>.InitiateTimeSeek(), that won't affect the SomeClass<Bar>._runningRealTime field, even if there is an inheritance relationship between the type parameters.

Static fields in generic classes | C# Online Compiler | .NET Fiddle[^]
 
Share this answer
 
Comments
Patrick Skelton 10-Aug-20 6:17am    
I have just discovered this rather obvious fact for myself. I discovered the initialisation for the static variable was being hit more than once, which is exactly what you would expect given what you have pointed out.

The clue should have been in the rather horrible code I was using to call the static functions: SessionStateBase<ISession>.InitiateTimeSeek();

I have moved the variable to a class that is not generic and is actually a much more natural home. Now everything works fine.

That will teach me to make comments like 'this class is an abstract generic class, though I struggle to see why this should be relevant'!

Thank you for the reply, Richard.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900