please put more threads and atomic operations support RRS feed

  • General discussion

  • hello,

    on dot-net 3.5 sp1 there are still very few concurrency classes and functions compared to what java has to offer.

    please put more of them on the next version of dot-net (4) .

    here are some examples of things that i really miss :

    1.Thread cannot be derived .it's annoying to create a new class that has the thread within it and manage it there.

    2.no atomic 'read','add','decrement','increment' operations on anything but the 'long' type.

    3.'compareExchange' has very weird usage and explanation and doesn't return true or false (succeeded or not) . instead it returns an object, which is usually not needed since you already have it from before of its execution.

    the explanation of this function should be :

    public static T CompareExchange<T>(ref T variable,T newValue,T expectedValue) - will return the old expectedValue if the comparison&setting were succeeded.

    if the name is problematic to change , just have the more standard name of 'compareAndSet' .
    4.there is no 'CompareExchange' that also does timestamps and there is also no 'CompareExchange' that also does flagging.on jave it is called 'AtomicStampedReference' and 'AtomicMarkableReference' (as classes) respectably.

    there are probably more that are missing(or at least hidden) features.

    please do consider adding those stuff into the new framework

    • Edited by LB636 Tuesday, April 27, 2010 3:13 AM
    Saturday, April 24, 2010 8:13 AM

All replies

  • Note that .NET 4 is finished and released already, so it is too late to add it there - http://msdn.microsoft.com/en-us/netframework/default.aspx

    1. What is motivation for deriving from System.Threading.Thread? How would you use it in such case?

    2. Check out System.Threading.Interlocked class - there are Int32 variants of all atomic operations. That should be sufficient, right?

    3. Returning the old value is generally recognized pattern (see e.g. wikipedia on this topic), which is not clearly better or worse than returning boolean. Therefore it is higly unlikely that it is going to change (it would break a lot of applications in the world), adding a new method would IMO just make things messy. You can easily wrap that function with your own which will return boolean if you want the boolean version that much.
    Also why do you think that its explanation is weird? - Remarks section on MSDN doc seems to me perfectly fine and says exactly what you propose.

    4. That's interesting class I never heard about. Please file a suggestion on MS Connect, so it gets routed to the correct production team and you will get official response. Please also describe there in which scenarios is such class useful.

    5. "There are probably more missing features" ... Well goal of .NET is not to copy everything from Java. .NET has its own model and it doesn't make sense to add random functions just because we can (that would make the APIs messy). Better approach is to add conceptual things which will make life of developers easier. If you know about concrete things which are not present in .NET, please file them as suggestions on MS Connect as I suggest in #4.

    Also check out Parallel Extensions, there are additional concurrency APIs.


    Saturday, April 24, 2010 11:54 PM
  • 0.after installing dot net 4 (which wasn't even suggested via the windows update), my visual C# became so buggy that i cannot find any way to re-install it correctly . it cannot show properties of GUI controls and the installation of it always show 3 errors .i also don't think that the dot net 4 replaced the other versions, and instead , as the rest of the versions did , was added . this is really annoying and it's really un-needed to have so many frameworks instead of one that is being updated. the new VC#2010 express , just like the previous one , doesn't have a portable installation and doesn't really allow me even to install the application on a different drive other than C:\ . when choosing a different drive letter, it's still being installed (or at least most of the app) on C, which is really annoying for having a good order . plus, it takes much more space than the previous version and still doesn't have so many great feature and customization options as Eclipse has.

    1.well, it's more comfortable than what we currently have on C#. the thread class itself describes what the thread does from within its implementation, instead of us giving it from outside.plus, you can add fields that are related to the thread itself (either things to put inserted into the class as parameters, or things to look at after the thread is done , as output variables). you could also have a shared variable for all of the threads which have the same goal.it just makes sense this way, and it takes much less code.

    2.there is not 'int' (or maybe 'int' is the same as 'int32'?) . as i mentioned , there is no 'Read' for anything but 'long'. also, using static functions on variables that almost always are used atomically is not intuitive to people who read the code . this is too close to how C works.

    3.i think that the explanation is weird because of the weird terms and parameters names that are used.for example: http://msdn.microsoft.com/en-us/library/cd0811yf.aspx location1? value?comparand? those names don't mean anything without any context to the rest. the description of them is also very confusing.i had to run a sample code i've created in order to check how it works. another example is 'decrement' and 'increment' . on java they are named exactly by the order of how they work. so, if you return the value after the increament, the function is called "incrementAndGet" . on msdn, they only say that the returned value is "The decremented value." . what does it mean? is it after it was decreamented or before? the name of the function does not give any clue about it too. even the word "exchange" is confusing. why is it exchange? it's not as if the values are exchanged - they are copied , they are being set based on what we need...

    4.those are at least 2 classes that are used for many cases and do not exist on C# . if you want to read further about concurrent data structures, you can check out the next great website: http://www.cs.tau.ac.il/~orish/mpp/?p=slides or( more updated version) : http://www.cs.tau.ac.il/~multi/?p=slides or read the book: http://www.amazon.com/gp/product/0123705916?ie=UTF8&tag=nirshavitshom-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=0123705916 a simple case for the atomicMarkableReference could be a lock free list (or queue) .i even used such a class for my own concurrent priority queue workshop using a data structure i called 'SkipQueue' and is based on ideas of many proffessors (they should get their credit,they are mentioned on the book) . for the new processors, there are even CAS (compareAndSet/CompareAndSwap/CompareExchange) operations that do 2 CASs at the same time . in fact you can read about it in the wikipedia link you gave me.

    5.well my life in Java for the developement in the concurrency world is much easier than the one of C# , at least that's how i see it.

    Sunday, April 25, 2010 7:43 PM
  • Note: These are my personal opinions and experiences, not any official Microsoft response.

    0.a. "my visual C# became so buggy" - I can hardly help you with this without more information. If you think it is a bug in C#, please create step-by-step repro (from sratch) and file a bug on MS Connect. If you think it is machine issue, you should be able to reinstall VS and .NET Framework.

    0.b. "also don't think that the dot net 4 replaced the other versions" - .NET 4 is major side-by-side release. It is not in-place replacement of previous .NET versions. This is the same story as between .NET 1.0 and 1.1, 1.1 and 2.0. Only versions 3.0 and 3.5 were extensions of previous version and in-place replacements of previous version parts. AFAIK this is the same story as with Java, right? Side-by-side installation provides better compatibility story. Some people like it, some don't, but there is not ultimate best solution.

    1. In .NET you can put all this stuff into your thread parameter (ParameterizedThreadStart). User fully controls the passed object and can get IMO the same flexibility. Moreover there is clear distinction what is .NET provided functionality (Thread class) and what is user functionality. Those two sets of functionality do not collide in this case.

    2. After reading Read description, my understanding is that it is for Int64 on 32-bit systems. CLR makes all 32-bit, 16-bit and 8-bit accesses atomic on all systems (it is likely defined in CLI). Therefore there is no need for Int32 version of this function.

    3.a. CompareExchange - All parameters have full description in Parameters and Remarks section. IMO the names are OK. If you think that you have better naming scheme, I would suggest you to add MSDN Wiki content to that page and ask people for feedback.
    I admit that I don't know why 'location1' has the number in its name, but I don't think it is a big issue.

    3.b. Increment and Decrement - "The decremented value." . what does it mean?
    Well this is absolutely clear to me what it means. I didn't even think that it might be unclear. It decrements the value atomically and returns the decremented result. What confusion is there? If you feel strong about your opinion, I would suggest to Rate/Give Feedback to the MSDN page (button on the top right).

    4. As I said, please file a suggestion on MSDN Connect. I wasn't interested in academic papers (I bet there are many). The real question for me is how often there are scenarios in real life and real projects when such concurrency primitives are necessary?
    IMO it is quite rare, so I don't see big issue in having these extended primitives in extra libraries (third party libraries or Parallel Extensions framework). I personally don't like frameworks which try to expose everything they can. Decisions what to make part of framework made on usefulness is IMO better.


    Sunday, April 25, 2010 9:31 PM
  • 0.a. well i still cannot find any way to uninstall and re-install VC# correctly. it always gives me errors. i cannot write down how to reproduce it since i never had this problem and do not know why it happens.

    0.b. first, Java does allow you (always) to have the new version replace the older one and supports backwards-compatability. second, i really don't know why we need this huge hassle of installing each and every one of the frameworks in order to be able to run any program that was created in dot-net.i (and many other people) almost always had problems with the updates of dot net, and used the cleanup tool of both microsoft and of Aaron Stebner's to try to solve them. sometimes i even had to re-install the OS itself because it took so much time to be installed correctly and i really needed it for working on it.

    1.still , when the function is outside the thread itself, you don't see the thread as an entity that runs in the background.you also can't have variables that are used by all of the threads of a certain class.

    2.what? i need to check out what machine i'm working on when using atomic operations? isn't dot net supposed to take care of such a thing? also, what about the other missing types (like bool) ?

    3.well i've read it again and again. they are unclear. english is not my main language but it doesn't mean i cannot read . too general names do not help with understanding their meaning. also, about the returned value of CAS , it's still quite odd since you already have the new value that you wish to put (and the old value) , so why do we always have to do the extra comparison by ourselves... the only advantage is that we could get the new updated value even if the CAS failed , so this might be useful in some cases... better names could be "variableToCompare","expectedValue","valueToSet" or something similar.

    4.well if it's important enough to add such functionalities for Intel, why can't microsoft follow and support having it ? if you think of this issue as you say , atomic operations can be thrown away too (you can use locks instead)or the opposite(since you can create your own locks using CAS operations for implementing mcs/clh/TTAS/TAS spin locks) ... the idea is that you give us the programmers an easier way to program and easier way to read the program later,even by other programmers,and also make it work well and make the usage of your functions as easy as other languages.in addition, i don't think Microsoft is against academic study using dot net, otherwise they wouldn't have had the dreamspark project.

    Monday, April 26, 2010 3:24 AM
  • 0.a. Post on installation forum and ask for help. With the description you provided it is impossible to guess what is going on.

    0.b. .NET allows you to run old applications on new .NET version too - via config file. As I said, "Side-by-side installation provides better compatibility story. Some people like it, some don't, but there is not ultimate best solution.". You are apparently in the second category. And .NET behavior is in the first category. IMO none is better.
    Re: Installation problems - Please send that feedback to the .NET installer team via MS Connect or Installation forum.

    1. Why cannot you have variables shared by all threads? Just use static variable on your thread-class. If you still think I misunderstood your point, please create a small example (~10 lines of code) and post it in a new separate thread (this one is rather overloaded).

    2. Why would you need to check out your machine? 32-bit, 16-bit and 8-bit operations (incl. bool) are IMO atomic - check the IL spec or maybe even C# spec. For 64-bit values use the Read API.

    3. Re: CAS - You are basically asking why Wikipedia considers it standard design. I have no asnwer to that. It's just a fact and apparently some people prefer one over another.

    4. I think you misunderstood my answer. I didn't say framework should be minimalistic and I dind't say that I am against academic studies. Also please note my previous comment that these are my personal opinions which are not Microsoft's official answer! Please do not consider them as such.


    Monday, April 26, 2010 7:29 AM
  • 0.a. ok, though i don't have much to write there - errors while installing and a bug while running VC# .

    0.b.what do you mean "none is better" ?

    1.how can i have my own thread class if i cannot have a class which derives from thread? only possible (yet uncomfortable) solution would be to wrap the thread , meaning that my class will have a thread object within it.

    2.atomic operations are not atomic variables. there is a difference. on atomic variables you can only do the basic things , but what about CAS operations etc... in any case, you wrote that "read" is for 32bit and 64bit . but there is no information of how to do so for all primitive types which are of C# (int,long,byte,float,double,...) . besides, i can only see "read" for 63bit. even if the other types of variables are atomic, it does mean that they shouldn't be mentioned and handled by their own functions,since as programmers, we shouldn't care of such technical things.if it means that much for whoever created the funtions, he could use a macro for the trivial cases,or, alternatively, the framework could inline them automatically.

    3.ok. it's just seems like an extra operation for an action that is much more common to use.

    4.this thread was created in order to request things from Microsoft to put on the new version of dot net. if you are not of Microsoft then i don't know what to tell you now ...

    • Edited by LB636 Tuesday, April 27, 2010 6:19 AM
    Tuesday, April 27, 2010 3:23 AM
  • 1. Please read my answer above: You can put your own class instance into thread parameter. Use that as "the thread" class.

    2. CompareExchange (CAS) is for everything - it has generic version. Read has only 64-bit version, because 32-bit, 16-bit and 8-bit Read implementations are in fact regular memory accesses I guess (please verify that in CLI spec as I suggested above). The same probably holds for single and double.

    4. Forums are place for users (community) to share information, ask questions each other, help each other, etc. Microsoft employess voluntarily contribute to the community mostly in their free time (like in my case). Some forums are monitored by Microsoft employees, some forums are monitored by MVPs and community users and some forums are not monitored at all. If you want to file suggestions or bugs and get official Microsoft response, then Microsoft Connect is the best place to do that.


    Tuesday, April 27, 2010 6:15 AM
  • 0.a. where is the forum that i can put my request for help? dot net 4 really messed up VC# and i tried so many times to fix it, with no success... i hope this forums is ok for this:


    1.what do you mean? can you give an example?

    2.please , in short, does Read work on 'long' , 'int' ,none or both?

    4.ok , thanks.

    Wednesday, April 28, 2010 8:20 PM
  • it also seems that some classes/structs do not have any documentation in VC# if they are thread safe or not.

    an example of this is the System.Drawing.Point struct , which is not thread safe according to the Internet, yet it's impossible to use CAS or any other atomic operation on it , even when using the <T> ...

    Monday, May 3, 2010 3:59 PM
  • That will probably require a lock.
    Out of curiosity: Are there atomic operations for arbitrary large structes in Java?
    Monday, May 3, 2010 7:23 PM
  • 0.a. I would recommend to use VS setup forum for the setup issue (check out this sticky post to get quicker answer). When it is resolved, check out if you can still reproduce the VC# issue and then file it in Visual C# IDE forum (try to provide step-by-step minimal repro from scratch for quicker answer).

    2. Read is only 64-bit. Why do you need 8-bit, 16-bit and 32-bit versions? What do you expect from them?

    Monday, May 3, 2010 7:32 PM
  • "That will probably require a lock.
    Out of curiosity: Are there atomic operations for arbitrary large structes in Java?"

    -really? anyway, another workaround could be to wrap it using a class, and there to use atomic operations as a reference. on java, there is no such a thing as structs. classes instances are referenced , so you just use the class called "atomicReference" and it works for any class you make ... structs are usually (except for pointing instead of setting) more efficient than classes , but they lack many features of classes. on java ,Point is a class and not a struct (since there is no such a thing on java ) , so using an "AtomicReference<Point>" is possible and will work as expected.

    "0.a. I would recommend to use VS setup forum for the setup issue (check out this sticky post to get quicker answer). When it is resolved, check out if you can still reproduce the VC# issue and then file it in Visual C# IDE forum (try to provide step-by-step minimal repro from scratch for quicker answer)."

    -thanks. will post there soon.

    "2. Read is only 64-bit. Why do you need 8-bit, 16-bit and 32-bit versions? What do you expect from them?"

    -why would i want to read of 'long' and 'int'? well usually they are used instead of 'int64' ...it's just that it's clearer to use functions that seem special (in this case, atomic operations) for variables that are spacial in their goal.

    Monday, May 3, 2010 8:50 PM
  • 5. "That will probably require a lock. Out of curiosity: Are there atomic operations for arbitrary large structes in Java?"
    OK, it's what I would naively expect. AtomicReference in Java is IMO just a wrapper for a lock, so no major difference in .NET. (Large) structs cannot be used in CAS and require a lock (or wrapping in a class that is used as lock).

    2. C# ECMA spec, 4th Edition - 12.5 "Atomicity of variable references" hopefully clarifies it:
    Reads and writes of the following data types shall be atomic: bool, char, byte, sbyte, short, ushort, uint, int, float, and reference types. In addition, reads and writes of enum types with an underlying type in the previous list shall also be atomic. Reads and writes of other types, including long, ulong, double, and decimal, as well as user-defined types, need not be atomic. Aside from the library functions designed for that purpose, there is no guarantee of atomic read-modify-write, such as in the case of increment or decrement.

    and CLI ECMA spec, 4th edition - I.12.6.6 "Atomic reads and writes":
    A conforming CLI shall guarantee that read and write access to properly aligned memory locations no larger than the native word size (the size of type native int) is atomic (see §12.6.2) when all the write accesses to a location are the same size. Atomic writes shall alter no bits other than those written. Unless explicit layout control (see Partition II (Controlling Instance Layout)) is used to alter the default behavior, data elements no larger than the natural word size (the size of a native int) shall be properly aligned. Object references shall be treated as though they are stored in the native word size.
    [Note: There is no guarantee about atomic update (read-modify-write) of memory, except for methods provided for that purpose as part of the class library (see Partition IV). An atomic write of a “small data item” (an item no larger than the native word size) is required to do an atomic read/modify/write on hardware that does not support direct writes to small data items. end note]
    [Note: There is no guaranteed atomic access to 8-byte data when the size of a native int is 32 bits even though some implementations might perform atomic operations when the data is aligned on an 8-byte boundary. end note]

    Monday, May 3, 2010 10:02 PM
  • "OK, it's what I would naively expect. AtomicReference in Java is IMO just a wrapper for a lock, so no major difference in .NET. (Large) structs cannot be used in CAS and require a lock (or wrapping in a class that is used as lock)."

    -it might seem to work this way, but it actually uses CAS on the reference(or pointer, however you wish to call it)  to the object . AtomicReference is more of a wrapper to a reference, just like AtomicInteger is like a wrapper to an integer .the language compiler/JIT can work on the wrapper in such a manner that it will be equivalent to using the static methods alone, so the performance shall be the same . this can be done via inlining .since the code is very short for each of the functions. that's also one of the few (again, few) cases that java can be faster than C/C++ .

    "C# ECMA spec, 4th Edition - 12.5 "Atomicity of variable references" hopefully clarifies it:..."

    -thanks. that clears some things a bit. it should be written very clearly at the Interlocked MSDN website, and somewhere on the intellisense notes .i wonder though why we can't have the AtomicMarkableReference and the AtomicStampedReference . the AtomicMarkableReference can be written quite easily - it consist of a pointer address value and a flag bit ,so doing a CAS will work on both. about AtomicStampedReference , i guess it does double CAS , as Intel already has this type of thing on some (relatively) new processors.

    another weird thing is that compareExchange doesn't support bool , except for using <bool> , which i'm not sure if it's better since i don't know how C# handles generics under the hood. i've also noticed that unlike java, C# allows using generics on primitives too , and not only classes (as far as i remember , java allows using only classes in their generics, don't know why) .

    EDIT:about the installation problem, i've found a solution : uninstall everything related to dot net and VC# (also using the cleanup tool and the one that cleans dot net framework) , then install VC# , and since it got errors, restart and run the installer again. now, about the empty toolbox and properties, run "VCSExpress.exe /ResetSkipPkgs" only once, and it will be fixed. i've found this solution on:


    now i wonder if i could have all of the versions of dot net framework being uninstalled and have only dot net framework v4 installed.

    Monday, May 3, 2010 10:27 PM