C# monitors (from a Java developer POV) - c#

I'm working on the port of a C#/directx game client to Java, so that I can learn some C# (as I am completely profane on it) and in the meanwhile improve my knowledge on a java opengl engine.
When I encounter something like the following:
Monitor.Enter(preloadDictionary);
try {
foreach (PreloadEntry entry in preloadDictionary.Values) {
if (entry.loaded) continue;
return entry;
}
} finally {
Monitor.Exit(preloadDictionary);
}
can i assume it is like the following?
syncronized(preloadDictionary) {
[...]
}
And in the case of:
Monitor.Enter(worldServerMap);
try {
worldServerMap[rv.WorldName] = entry;
Monitor.PulseAll(worldServerMap);
} finally {
Monitor.Exit(worldServerMap);
}
is the additional PulseAll() like a notifyAll() to wake up all thread waiting on the resource? (but i could not find any place in the code where Monitor.Wait() is called).

lock(x) is itentical to Monitor.Enter then Monitor.Exit in the finally. It is a langauge shortcut.
If you ask me, it is one of the weaker parts of the C# language - simply because while it was nice while there was a MINOTIR, these days there are various versions of monitors (slim, spinlock etc.) and lock only supports one of them. It is convenient, but I am not sure it is wise ;)
is the additional PulseAll() like a notifyAll() to wake up all thread
waiting on the resource? (but i could not find any place in the code
where Monitor.Wait() is called).
The PulseAll makes little sense unless you have an explicit wait, possibly from other threads not wanting to Enter. Enter waits if it can not get a lock, so Exit is enough to make normal synchronization.
I would start looking for a Wait or something else - PulseAll on a MOnitor makes only sense if you have threads waiting WITHOUT trying to Enter at this stage. It could lead to a bad design issue that basically has them waiting then get pulsed then try to enter, it could be part of a non blocking design of some dsort - hard to say, but it is unusual. Unless you can find a Wait somewhere in your code, I would likely try killing the PulseAll and see what happens.

Related

waiting for a second every time in a loop in c# using Thread.Sleep

i'm trying to print "p" to the screen every second.
when I run this:
while (true)
Thread.Sleep(1000);
Console.WriteLine("p");
it doesn't print at all.
But when I run this:
while (true)
Console.WriteLine("p");
Thread.Sleep(1000);
Its printing without waiting at all. Can somebody please explain this to me and suggest a fix?
You are not looping the whole code
This :
while (true)
Thread.Sleep(1000);
Console.WriteLine("p");
Is the same as this :
while (true)
{
Thread.Sleep(1000);
}
Console.WriteLine("p");
You need to explicitly set your braces around all the lines you want the loop to perform otherwise it only loop on the next instruction.
Something like this is what you are looking for :
while (true)
{
Thread.Sleep(1000);
Console.WriteLine("p");
}
why didn't it work without braces?
C# is not Python. In Python, program structure is indicated by spaces. In C# whitespace is ignored entirely and program structure is determined by the grammar of the language.
In C# a block of the form { any number of statements } is itself a statement.
The grammar of while is
while( an expression that can be evaluated to bool )
a single statement
But since { ... } is a single statement, if you want multiple statements in the body of your while, or if, or for or foreach and so on, you use a block.
Incidentally, you should not be using Thread.Sleep in the first place. It should only be used in testing code. Threads are expensive program resources; do not pay them to sleep! If you want to introduce a delay, then there are two things to do. In an event-driven program, start a timer and then handle the timer event when it goes off. Or, make your program asynchronous and await a Task.Delay. Sleeping is a bad practice and indicates that there is some flaw in your program design.
Now, you might say, hey, this is a console program and I genuinely want to introduce a delay in my user experience, and I don't have any events processing in the background, and so on, so why not Sleep? And I can understand that argument; it is convenient. However, (1) get in good habits now while you are still a beginner and you won't have to break them later, and (2) programs evolve. At some point you're going to want to write a program that stays interactive and responds to user keypresses, or network traffic, or some other such thing, while the UI is paused; if your threads are asleep, they're not responding to those events.

How to pause and resume a thread without use threading logic inside it

i cannot put threading logic inside of Run method, the run method executes many operation in database.
like this:
void Run()
{
while (true)
{
InsertEntitiesA();
DeleteEntitiesA();
UpdateEntitiesA();
InsertEntitiesB();
DeleteEntitiesB();
UpdateEntitiesB();
InsertEntitiesC();
DeleteEntitiesC();
UpdateEntitiesC();
}
}
if i pause it and the thread is on DeleteEntitiesB() i want it to stop there, and then when i resume i want it to start from where it's been stopped, DeleteEntitiesB() on the line it's been stopped.
is there a way to perform it?
i dont think there is =(
Ps: Like i said the Run method cannot be modified
You can do this using Thread.Suspend and Thread.Resume but it is generally a very bad idea. As you don't know where the thread is in its execution when you call these you have no idea whether it is in anything critical. If it is in something critical all sorts of havoc can ensue, this is probably why Microsoft decided to obsolete the methods.
It cannot be done without the thread's cooperation. What happens if you suspend the thread while it holds a critical lock? What if it holds a lock that the thread that is going to unsuspend it needs?

Do zombies exist ... in .NET?

I was having a discussion with a teammate about locking in .NET. He's a really bright guy with an extensive background in both lower-level and higher-level programming, but his experience with lower level programming far exceeds mine. Anyway, He argued that .NET locking should be avoided on critical systems expected to be under heavy-load if at all possible in order to avoid the admittedly small possibility of a "zombie thread" crashing a system. I routinely use locking and I didn't know what a "zombie thread" was, so I asked. The impression I got from his explanation is that a zombie thread is a thread that has terminated but somehow still holds onto some resources. An example he gave of how a zombie thread could break a system was a thread begins some procedure after locking on some object, and then is at some point terminated before the lock can be released. This situation has the potential to crash the system, because eventually, attempts to execute that method will result in the threads all waiting for access to an object that will never be returned, because the thread that is using the locked object is dead.
I think I got the gist of this, but if I'm off base, please let me know. The concept made sense to me. I wasn't completely convinced that this was a real scenario that could happen in .NET. I've never previously heard of "zombies", but I do recognize that programmers who have worked in depth at lower levels tend to have a deeper understanding of computing fundamentals (like threading). I definitely do see the value in locking, however, and I have seen many world class programmers leverage locking. I also have limited ability to evaluate this for myself because I know that the lock(obj) statement is really just syntactic sugar for:
bool lockWasTaken = false;
var temp = obj;
try { Monitor.Enter(temp, ref lockWasTaken); { body } }
finally { if (lockWasTaken) Monitor.Exit(temp); }
and because Monitor.Enter and Monitor.Exit are marked extern. It seems conceivable that .NET does some kind of processing that protects threads from exposure to system components that could have this kind of impact, but that is purely speculative and probably just based on the fact that I've never heard of "zombie threads" before. So, I'm hoping I can get some feedback on this here:
Is there a clearer definition of a "zombie thread" than what I've explained here?
Can zombie threads occur on .NET? (Why/Why not?)
If applicable, How could I force the creation of a zombie thread in .NET?
If applicable, How can I leverage locking without risking a zombie thread scenario in .NET?
Update
I asked this question a little over two years ago. Today this happened:
Is there a clearer definition of a "zombie thread" than what I've explained here?
Seems like a pretty good explanation to me - a thread that has terminated (and can therefore no longer release any resources), but whose resources (e.g. handles) are still around and (potentially) causing problems.
Can zombie threads occur on .NET? (Why/Why not?)
If applicable, How could I force the creation of a zombie thread in .NET?
They sure do, look, I made one!
[DllImport("kernel32.dll")]
private static extern void ExitThread(uint dwExitCode);
static void Main(string[] args)
{
new Thread(Target).Start();
Console.ReadLine();
}
private static void Target()
{
using (var file = File.Open("test.txt", FileMode.OpenOrCreate))
{
ExitThread(0);
}
}
This program starts a thread Target which opens a file and then immediately kills itself using ExitThread. The resulting zombie thread will never release the handle to the "test.txt" file and so the file will remain open until the program terminates (you can check with process explorer or similar). The handle to "test.txt" won't be released until GC.Collect is called - it turns out it is even more difficult than I thought to create a zombie thread that leaks handles)
If applicable, How can I leverage locking without risking a zombie thread scenario in .NET?
Don't do what I just did!
As long as your code cleans up after itself correctly (use Safe Handles or equivalent classes if working with unmanaged resources), and as long as you don't go out of your way to kill threads in weird and wonderful ways (safest way is just to never kill threads - let them terminate themselves normally, or through exceptions if necessary), the only way that you are going to have something resembling a zombie thread is if something has gone very wrong (e.g. something goes wrong in the CLR).
In fact its actually surprisingly difficult to create a zombie thread (I had to P/Invoke into a function that esentially tells you in the documentation not to call it outside of C). For example the following (awful) code actually doesn't create a zombie thread.
static void Main(string[] args)
{
var thread = new Thread(Target);
thread.Start();
// Ugh, never call Abort...
thread.Abort();
Console.ReadLine();
}
private static void Target()
{
// Ouch, open file which isn't closed...
var file = File.Open("test.txt", FileMode.OpenOrCreate);
while (true)
{
Thread.Sleep(1);
}
GC.KeepAlive(file);
}
Despite making some pretty awful mistakes, the handle to "test.txt" is still closed as soon as Abort is called (as part of the finalizer for file which under the covers uses SafeFileHandle to wrap its file handle)
The locking example in C.Evenhuis answer is probably the easiest way to fail to release a resource (a lock in this case) when a thread is terminated in a non-weird way, but thats easily fixed by either using a lock statement instead, or putting the release in a finally block.
See also
Subtleties of C# IL
codegen
for a very subtle case where an exception can prevent a lock from
being released even when using the lock keyword (but only in .Net 3.5 and earlier)
Locks and exceptions do not
mix
I've cleaned up my answer a bit, but left the original one below for reference
It’s the first time I've heard of the term zombies so I'll assume its definition is:
A thread that has terminated without releasing all of its resources
So given that definition, then yes, you can do that in .NET, as with other languages (C/C++, java).
However, I do not think this as a good reason not to write threaded, mission critical code in .NET. There may be other reasons to decide against .NET but writing off .NET just because you can have zombie threads somehow doesn't make sense to me. Zombie threads are possible in C/C++ (I'd even argue that it’s a lot easier to mess up in C) and a lot of critical, threaded apps are in C/C++ (high volume trading, databases etc).
Conclusion
If you are in the process of deciding on a language to use, then I suggest you take the big picture into consideration: performance, team skills, schedule, integration with existing apps etc. Sure, zombie threads are something that you should think about, but since it’s so difficult to actually make this mistake in .NET compared to other languages like C, I think this concern will be overshadowed by other things like the ones mentioned above. Good luck!
Original Answer
Zombies† can exist if you don't write proper threading code. The same is true for other languages like C/C++ and Java. But this is not a reason not to write threaded code in .NET.
And just like with any other language, know the price before using something. It also helps to know what is happening under the hood so you can foresee any potential problems.
Reliable code for mission critical systems is not easy to write, whatever language you're in. But I'm positive it’s not impossible to do correctly in .NET. Also AFAIK, .NET threading is not that different from threading in C/C++, it uses (or is built from) the same system calls except for some .net specific constructs (like the light weight versions of RWL and event classes).
†first time I've heard of the term zombies but based on your description, your colleague probably meant a thread that terminated without release all resources. This could potentially cause a deadlock, memory leak or some other bad side effect. This is obviously not desirable but singling out .NET because of this possibility is probably not a good idea since it’s possible in other languages too. I'd even argue that it’s easier to mess up in C/C++ than in .NET (especially so in C where you don't have RAII) but a lot of critical apps are written in C/C++ right? So it really depends on your individual circumstances. If you want to extract every ounce of speed from your application and want to get as close to bare metal as possible, then .NET might not be the best solution. If you are on a tight budget and do a lot of interfacing with web services/existing .net libraries/etc then .NET may be a good choice.
Right now most of my answer has been corrected by the comments below. I won't delete the answer because I need the reputation points because the information in the comments may be valuable to readers.
Immortal Blue pointed out that in .NET 2.0 and up finally blocks are immune to thread aborts. And as commented by Andreas Niedermair, this may not be an actual zombie thread, but the following example shows how aborting a thread can cause problems:
class Program
{
static readonly object _lock = new object();
static void Main(string[] args)
{
Thread thread = new Thread(new ThreadStart(Zombie));
thread.Start();
Thread.Sleep(500);
thread.Abort();
Monitor.Enter(_lock);
Console.WriteLine("Main entered");
Console.ReadKey();
}
static void Zombie()
{
Monitor.Enter(_lock);
Console.WriteLine("Zombie entered");
Thread.Sleep(1000);
Monitor.Exit(_lock);
Console.WriteLine("Zombie exited");
}
}
However when using a lock() { } block, the finally would still be executed when a ThreadAbortException is fired that way.
The following information, as it turns out, is only valid for .NET 1 and .NET 1.1:
If inside the lock() { } block an other exception occurs, and the ThreadAbortException arrives exactly when the finally block is about to be ran, the lock is not released. As you mentioned, the lock() { } block is compiled as:
finally
{
if (lockWasTaken)
Monitor.Exit(temp);
}
If another thread calls Thread.Abort() inside the generated finally block, the lock may not be released.
This isn't about Zombie threads, but the book Effective C# has a section on implementing IDisposable, (item 17), which talks about Zombie objects which I thought you may find interesting.
I recommend reading the book itself, but the gist of it is that if you have a class either implementing IDisposable, or containing a Desctructor, the only thing you should be doing in either is releasing resources. If you do other things here, then there is a chance that the object will not be garbage collected, but will also not be accessible in any way.
It gives an example similar to below:
internal class Zombie
{
private static readonly List<Zombie> _undead = new List<Zombie>();
~Zombie()
{
_undead.Add(this);
}
}
When the destructor on this object is called, a reference to itself is placed on the global list, meaning it stays alive and in memory for the life of the program, but isn't accessible. This may mean that resources (particularly unmanaged resources) may not be fully released, which can cause all sorts of potential issues.
A more complete example is below. By the time the foreach loop is reached, you have 150 objects in the Undead list each containing an image, but the image has been GC'd and you get an exception if you try to use it. In this example, I am getting an ArgumentException (Parameter is not valid) when I try and do anything with the image, whether I try to save it, or even view dimensions such as height and width:
class Program
{
static void Main(string[] args)
{
for (var i = 0; i < 150; i++)
{
CreateImage();
}
GC.Collect();
//Something to do while the GC runs
FindPrimeNumber(1000000);
foreach (var zombie in Zombie.Undead)
{
//object is still accessable, image isn't
zombie.Image.Save(#"C:\temp\x.png");
}
Console.ReadLine();
}
//Borrowed from here
//http://stackoverflow.com/a/13001749/969613
public static long FindPrimeNumber(int n)
{
int count = 0;
long a = 2;
while (count < n)
{
long b = 2;
int prime = 1;// to check if found a prime
while (b * b <= a)
{
if (a % b == 0)
{
prime = 0;
break;
}
b++;
}
if (prime > 0)
count++;
a++;
}
return (--a);
}
private static void CreateImage()
{
var zombie = new Zombie(new Bitmap(#"C:\temp\a.png"));
zombie.Image.Save(#"C:\temp\b.png");
}
}
internal class Zombie
{
public static readonly List<Zombie> Undead = new List<Zombie>();
public Zombie(Image image)
{
Image = image;
}
public Image Image { get; private set; }
~Zombie()
{
Undead.Add(this);
}
}
Again, I am aware you were asking about zombie threads in particular, but the question title is about zombies in .net, and I was reminded of this and thought others may find it interesting!
On critical systems under heavy load, writing lock-free code is better primarily because of the performance improvments. Look at stuff like LMAX and how it leverages "mechanical sympathy" for great discussions of this. Worry about zombie threads though? I think that's an edge case that's just a bug to be ironed out, and not a good enough reason not to use lock.
Sounds more like your friend is just being fancy and flaunting his knowledege of obscure exotic terminology to me! In all the time I was running the performance labs at Microsoft UK, I never came across an instance of this issue in .NET.
1.Is there a clearer definition of a "zombie thread" than what I've explained here?
I do agree that "Zombie Threads" exist, it's a term to refer to what happens with Threads that are left with resources that they don't let go of and yet don't completely die, hence the name "zombie," so your explanation of this referral is pretty right on the money!
2.Can zombie threads occur on .NET? (Why/Why not?)
Yes they can occur. It's a reference, and actually referred to by Windows as "zombie": MSDN uses the Word "Zombie" for Dead processes/threads
Happening frequently it's another story, and depends on your coding techniques and practices, as for you that like Thread Locking and have done it for a while I wouldn't even worry about that scenario happening to you.
And Yes, as #KevinPanko correctly mentioned in the comments, "Zombie Threads" do come from Unix which is why they are used in XCode-ObjectiveC and referred to as "NSZombie" and used for debugging. It behaves pretty much the same way... the only difference is an object that should've died becomes a "ZombieObject" for debugging instead of the "Zombie Thread" which might be a potential problem in your code.
I can make zombie threads easily enough.
var zombies = new List<Thread>();
while(true)
{
var th = new Thread(()=>{});
th.Start();
zombies.Add(th);
}
This leaks the thread handles (for Join()). It's just another memory leak as far as we are concerned in the managed world.
Now then, killing a thread in a way that it actually holds locks is a pain in the rear but possible. The other guy's ExitThread() does the job. As he found, the file handle got cleaned up by the gc but a lock around an object wouldn't. But why would you do that?

Game design - main loop aborting - Is there a better way than Abort() and ResetAbort()?

I have a C# threading program (a game), that stops with a boolean (as most articles recommend).
while (gameContinueRun)
{
createRound();
line1;
line2;
line3;
line4;
endRound();
}
Some code lines lock the game and wait until other thread will release it:
lock (stateSync)
{
Monitor.Wait(stateSync)
}
To stop the thread from another thread I set the boolean to false:
if (cancel)
{
gameContinueRun= false;
}
Everything works nicely, but I still need to wait until the end of the current loop (round).
I want to end the loop, to break all work in the middle (abort game). Another thing is to be able to restart the loop (open new round). Or in other words, two things:
abort the game
cancel the current round and start a new one
I thought about it, and got a couple of ways:
Unlock all locks, and check after every code line:
if (!cancelRound)
{
line1;
}
if (!cancelRound)
{
line2;
}
if (!cancelRound)
{
line3;
}
if (!cancelRound)
{
line4;
}
Not very nice, and very exhausting if one have lots of code lines to cover...
Use Thread.Abort(), catching the Exception and resetAbort() if needed.
Use goto and labels (which I assume is even uglier then aborting).
Which way is better? Or moreover, is there a better recommended way?
Try looking at WaitHandle.WaitAny(WaitHandle[]) method for your locks.
Then you can work with arrays of AutoResetEvent or ManualResetEvent - one for exiting and all the rest for the locking.
See:
http://msdn.microsoft.com/en-us/library/yy12yx1f.aspx
I usually end up writing lots of
if (m_state != GameState.Active) {
return;
} // if
kind of code.
Maybe you could use custom attribute, similar to that of code access security. And do something like
[RequireState(GameState.Active)]
void DoSomething();
It not entirely clear what you are trying to do, but it looks like you want some form of inter-thread communication. However, it is usual for the game loop to control the other threads, not to be controlled itself. So instead you'd have:
function GameLoop
start threads
while (continuing game loop)
tell threads to do something
wait for threads to finish doing something
end while
tell threads to stop
wait for threads to terminate
end function
Your solution using the lock and Monitor.Wait is unusual and probably not robust enough. I think you need to do some research into multi-threading and maybe tryout some classical problems (the dining philosophers for example) and then redesign your code.

How can I check if a function is being called on a particular Thread?

If I have Thread A which is the main Application Thread and a secondary Thread. How can I check if a function is being called within Thread B?
Basically I am trying to implement the following code snippit:
public void ensureRunningOnCorrectThread()
{
if( function is being called within ThreadB )
{
performIO()
}
else
{
// call performIO so that it is called (invoked?) on ThreadB
}
}
Is there a way to perform this functionality within C# or is there a better way of looking at the problem?
EDIT 1
I have noticed the following within the MSDN documentation, although Im a dit dubious as to whether or not its a good thing to be doing! :
// if function is being called within ThreadB
if( System.Threading.Thread.CurrentThread.Equals(ThreadB) )
{
}
EDIT 2
I realise that Im looking at this problem in the wrong way (thanks to the answers below who helped me see this) all I care about is that the IO does not happen on ThreadA. This means that it could happen on ThreadB or indeed anyother Thread e.g. a BackgroundWorker. I have decided that creating a new BackgroundWorker within the else portion of the above f statement ensures that the IO is performed in a non-blocking fashion. Im not entirely sure that this is the best solution to my problem, however it appears to work!
Here's one way to do it:
if (System.Threading.Thread.CurrentThread.ManagedThreadId == ThreadB.ManagedThreadId)
...
I don't know enough about .NET's Thread class implementation to know if the comparison above is equivalent to Equals() or not, but in absence of this knowledge, comparing the IDs is a safe bet.
There may be a better (where better = easier, faster, etc.) way to accomplish what you're trying to do, depending on a few things like:
what kind of app (ASP.NET, WinForms, console, etc.) are you building?
why do you want to enforce I/O on only one thread?
what kind of I/O is this? (e.g. writes to one file? network I/O constrained to one socket? etc.)
what are your performance constraints relative to cost of locking, number of concurrent worker threads, etc?
whether the "else" clause in your code needs to be blocking, fire-and-forget, or something more sophisticated
how you want to deal with timeouts, deadlocks, etc.
Adding this info to your question would be helpful, although if yours is a WinForms app and you're talking about user-facing GUI I/O, you can skip the other questions since the scenario is obvious.
Keep in mind that // call performIO so that it is called (invoked?) on ThreadB implementation will vary depending on whether this is WinForms, ASP.NET, console, etc.
If WinForms, check out this CodeProject post for a cool way to handle it. Also see MSDN for how this is usually handled using InvokeRequired.
If Console or generalized server app (no GUI), you'll need to figure out how to let the main thread know that it has work waiting-- and you may want to consider an alternate implementation which has a I/O worker thread or thread pool which just sits around executing queued I/O requests that you queue to it. Or you might want to consider synchronizing your I/O requests (easier) instead of marshalling calls over to one thread (harder).
If ASP.NET, you're probably implementing this in the wrong way. It's usually more effective to use ASP.NET async pages and/or to (per above) synchronize snchronizing to your I/O using lock{} or another synchronization method.
What you are trying to do is the opposite of what the InvokeRequired property of a windows form control does, so if it's a window form application, you could just use the property of your main form:
if (InvokeRequired) {
// running in a separate thread
} else {
// running in the main thread, so needs to send the task to the worker thread
}
The else part of your snippet, Invoking PerformIO on ThreadB is only going to work when ThreadB is the Main thread running a Messageloop.
So maybe you should rethink what you are doing here, it is not a normal construction.
Does your secondary thread do anything else besides the performIO() function? If not, then an easy way to do this is to use a System.Threading.ManualResetEvent. Have the secondary thread sit in a while loop waiting for the event to be set. When the event is signaled, the secondary thread can perform the I/O processing. To signal the event, have the main thread call the Set() method of the event object.
using System.Threading;
static void Main(string[] args)
{
ManualResetEvent processEvent = new ManualResetEvent(false);
Thread thread = new Thread(delegate() {
while (processEvent.WaitOne()) {
performIO();
processEvent.Reset(); // reset for next pass...
}
});
thread.Name = "I/O Processing Thread"; // name the thread
thread.Start();
// Do GUI stuff...
// When time to perform the IO processing, signal the event.
processEvent.Set();
}
Also, as an aside, get into the habit of naming any System.Threading.Thread objects as they are created. When you create the secondary thread, set the thread name via the Name property. This will help you when looking at the Threads window in Debug sessions, and it also allows you to print the thread name to the console or the Output window if the thread identity is ever in doubt.

Categories

Resources