←back to thread

176 points chhum | 8 comments | | HN request time: 1.466s | source | bottom
Show context
PathOfEclipse ◴[] No.44006859[source]
I've been working in .NET/C# for the past few years, and while I'm happy with it, I still think the JVM/Java are the best ecosystem overall I've worked in. It's amazing how many things the Java ecosystem gets right that .NET gets wrong.

For instance, Java introduced the fork/join pool for work stealing and recommended it for short-lived tasks that decomposed into smaller tasks. .NET decided to simply add work-stealing to their global thread pool. The result: sync-over-async code, which is the only way to fold an asynchronous library into a synchronous codebase, frequently results in whole-application deadlocks on .NET, and this issue is well-documented: https://blog.stephencleary.com/2012/07/dont-block-on-async-c...

Notice the solution in this blog is "convert all your sync code to async", which can be infeasible for a large existing codebase.

There are so many other cases like this that I run into. While there have been many mistakes in the Java ecosystem they've mostly been in the library/framework level so it's easier to move on when people finally realize the dead end. However, when you mess up in the standard library, the runtime, or language, it's very hard to fix, and Java seems to have gotten it more right here than anywhere else.

replies(3): >>44007589 #>>44009996 #>>44010560 #
1. neonsunset ◴[] No.44007589[source]
> frequently results in whole-application deadlocks on .NET

Tell us you don't write any sort of .NET code without telling us so explicitly.

You should pick a platform you have better command of for back-handed comments.

Or at least you should try to do a better job than referencing a post from 13 years ago.

replies(2): >>44007813 #>>44007915 #
2. PathOfEclipse ◴[] No.44007813[source]
That's a very harsh reply with zero evidence behind it. Based on your response, I am willing to bet I understand the platform better than you do. And the deadlocks I'm referring to are happening in apps written by other people who've been in the .NET ecosystem exclusively for more than a decade, or even two decades.

Here's an article from 5 years ago:

https://medium.com/criteo-engineering/net-threadpool-starvat...

But does citing a more-recent article matter to you? Probably not. A source being 13 years old only matters if something relevant has changed since then, and you certainly couldn't be bothered to point out any relevant change to support your otherwise fallacious and misleading comment.

What actually amazes me most about this is that people in .NET seem to want to blame the person writing sync-over-async code like they are doing something wrong, even going so far as to call it an "anti-pattern", when in reality it is the fault of poor decision-making from the .NET team to fold work-stealing into the global thread queue. The red-blue function coloring problem is real, and you can't make it go away by pretending everyone can just rewrite all their existing synchronous code and no other solution is needed.

If all you know is one ecosystem, then it seems you are susceptible to a form of Stockholm syndrome when that ecosystem abuses you.

replies(1): >>44008167 #
3. ◴[] No.44007915[source]
4. neonsunset ◴[] No.44008167[source]
> But does citing a more-recent article matter to you?

It does. For example, starting with .NET 6 there is a pure C# threadpool implementation that acts differently under problematic scenarios.

You do not understand performance profile and UX pros/cons of why async model is better than opting into stackful coroutine based design. You're probably of opinion that the only way to use async is to always await immediately rather than idiomatically composing tasks/futures.

I'm certain you're basing this off of your personal experience from more than a decade ago of some forsaken codebase written in an especially sloppy way. Do you know why sloppy async code is possible in the first place? That's because even the initial threadpool implementation was so resilient.

Because that's where this kind of sentiment from supposed "seasoned experts" on .NET stack usually comes from.

Moreover, there isn't a single mention that the real way to get into actual deadlock situation is when dealing with applications enriched with synchronization context. You will only ever run into this in GUI scenarios, where .NET's implementation of async continues to be a better alternative to reactive frameworks or, worse, manual threading.

> If all you know is one ecosystem, then it seems you are susceptible to a form of Stockholm syndrome when that ecosystem abuses you.

Pathetic attempt at strawman.

My opinion of .NET kept improving since .NET Core 2.1/3.1 days up until today because of researching the details of and getting exposed to other languages (like Rust, Go, Java, Kotlin, Swift, C and C++, you name it).

Hell, I'm not even arguing that what we have today is the holy grail of writing concurrent and parallel programs, only that most other alternatives are worse.

replies(1): >>44008316 #
5. PathOfEclipse ◴[] No.44008316{3}[source]
> For example, starting with .NET 6 there is a pure C# threadpool implementation that acts differently under problematic scenarios.

We're seeing this issue entirely in .NET core. We started on .NET 6, are currently on .NET 8, and will likely migrate to 10 soon after it is released. It's again worth mentioning that you provide zero evidence that .NET 6 solves this problem in any way. Although, as we will see below, it seems like you don't even understand the problem!

> I'm certain you're basing this off of your personal experience from more than a decade ago of some forsaken codebase written in an especially sloppy way.

No, I'm referring to code written recently, at the job I work at now, at which I've been involved in discussions about, and implementations of, workarounds for the issue.

> Moreover, there isn't a single mention that the real way to get into actual deadlock situation is when dealing with applications enriched with synchronization context.

100% false. This deadlock issue has nothing to do with synchronization contexts. Please actually read the 2020 article I linked as it explains the issue much better.

> Pathetic attempt at strawman.

I realize responding to this is to just fight pettiness with more pettiness, but I can't resist. You should probably look up the definition of a strawman argument since you are using the word incorrectly.

replies(1): >>44008395 #
6. neonsunset ◴[] No.44008395{4}[source]
To me a claim "how many things the Java ecosystem gets right that .NET gets wrong" borders on insanity if we consider having to interact with Maven or even Gradle on a daily basis after .NET's CLI and NuGet, or having to deal with type erasure in generics, or weird stream API shape, or not having common slice and sequence types that everything nicely unifies under because primitives cannot be generalized, or not being able to author properties and extension methods, creating dozens upon dozens of type copies or just boilerplate accessors, or having to tolerate Hibernate after EF Core, and so on and so forth.

As for async and tasks - have you ever considered just not writing the code that is so bad it managed to bypass cooperative blocking detection and starvation mitigations? It's certainly an impressive achievement if you managed to pull this off while starting with .NET 6.

Edit: I agree with the subsequent reply and you are right. Concurrency primitives are always a contentious topic.

replies(2): >>44008588 #>>44009398 #
7. PathOfEclipse ◴[] No.44008588{5}[source]
I have no problem with you preferring .NET to Java, and I apologize that my first-cited article was not the best one to share to describe the problem (I should have read it more carefully first), but if you had responded with something like:

"Your deadlock scenario is related to synchronization contexts and can be avoided by ..."

rather than:

"You clearly don't know what you're talking about (but I won't bother telling you why)"

Then we could have had a much more productive and pleasant conversation. I would have responded with:

"Sorry, that article wasn't the right one to share. Here is a better one. The issue I am talking about isn't synchronization context-related at all. It's actually much more insidious."

8. octo888 ◴[] No.44009398{5}[source]
> having to tolerate Hibernate after EF Core,

Enjoying or tolerating Hibernate is undiagnosed Stockholm Syndrome :D