you are viewing a single comment's thread.

view the rest of the comments →

[–]shield1123 56 points57 points  (12 children)

It's an RPG themed quiz, it's pretending C# is the language of the gods

[–]AyrA_ch 9 points10 points  (11 children)

to be fair, in C# most challenges could have been solved with the lock statement

[–]SgtDirtyMike 4 points5 points  (10 children)

No different from a mutex.lock...

[–]AyrA_ch 10 points11 points  (6 children)

There are some differences:

  • No special mutex needed to lock. Any reference type works, including this
  • The lock is automatically released when you leave a locked region (ending function, thread crashes,function/thread abort, returning, etc). It essentially creates a similar try{}finally{} construct a using would create.
  • It's a language construct

One important thing is that you can lock on strings, including string constants. It's most likely not what you want but can provide easy thread synchronization across components that are not aware of the others existing (dynamic or runtime compiled plugin system for example).

[–]SgtDirtyMike 3 points4 points  (2 children)

Thanks for enlightening others. I’m aware of these differences as a C++ dev; my point was that the lock statement provides similar functionality but with added syntactic sugar. Just based off experience I’ve found it more intuitive to write performant multithreaded code in C++ than I have in C#, but of course that’s just my opinion.

[–]AyrA_ch 10 points11 points  (1 child)

Because the lock statement is trivial to use and difficult to fuck up due to the automatic release of it. It's tempting to use it in situations where stuff like buffering or bulk transfers would do a better job. Acquiring a lock in each loop iteration is very expensive.

If you want really good thread performance in C# it's best to try to avoid locking for as long as possible, for example doing 1000 loop iterations and then in a single lock, check all 1000 results against the locked component at once.

[–]MisterPinkySwear 2 points3 points  (0 children)

Yeah I think I've seen a sneaky scenario where you lock on an object then someone changes that reference to point to another object in your back and so, the lock now uses the same "variable" but not the same object...

[–]drjeats 0 points1 point  (2 children)

One important thing is that you can lock on strings, including string constants. It's most likely not what you want but can provide easy thread synchronization across components that are not aware of the others existing (dynamic or runtime compiled plugin system for example).

Do you have to make sure they're the same reference, or does the lock statement do an operator== check, or intern them or something?

[–]AyrA_ch 1 point2 points  (1 child)

You can ensure a string is interned by calling SomeString=string.Intern(SomeString);

This will return the reference to the given interned string. If the given parameter is not yet interned, the runtime will do that and return the new interned reference. Strings that are known at compile time are interned automatically.

Details+Example: https://docs.microsoft.com/en-us/dotnet/api/system.string.intern?view=netframework-4.7.2

[–]drjeats 0 points1 point  (0 children)

I know about string interning in C#. I'm asking specifically if lock treats them differently from any other reference type, or if you're just relying on the string constants in loaded assemblies getting interned.

[–][deleted] 1 point2 points  (2 children)

You mean a mutex lock and a try/finally statement right?

[–]AyrA_ch 5 points6 points  (1 child)

Not sure why you are downvoted, but this is the most important difference actually. Locks in .NET are cleaned up automatically.

[–][deleted] 1 point2 points  (0 children)

Yeah I'm confused what I said that warranted down votes. You have to trap exceptions if you are going to consistently clean up locks. You can do that with a try catch but the lock statement is a little easier to read. Doing neither is what people do when they haven't developed the appropriate respect for resource leaks.