Top all-time · #2684
Stephen Cleary
Personal blog · blog.stephencleary.comprogramming
Stephen Cleary's personal blog at blog.stephencleary.com covers programming. Since 2014, 29 different Hacker News readers have linked it 37 times, most often “There is no thread (2013)”. It is still writing: the last post was on 2024-12-03, and you can follow it by feed.
Too few sampled comments (28) to say how often HN recommends it.?
Why HN links it
HN readers link Stephen Cleary's blog for explanations of async/await and threading in .NET, notably "There is no thread" and advice on not blocking on async code. Several comments point readers to it.
Summarised by Claude from a sample of 28 HN comments that link here. Each comment is marked recommending, critical or neutral (citing without judging); how this works.
Stephen Cleary's blog: async/await, programming, language design, and other sundry computer science topics.
Most-linked posts?
- There is no thread (2013)11 people · 13 mentions · first linked 2017-05-17
- /2012/07/dont-block-on-async-code.html6 people · 6 mentions · first linked 2019-12-26
- There are no threads in async4 people · 4 mentions · first linked 2014-01-26
- Recursive (Re-Entrant) Locks (2013)2 people · 2 mentions · first linked 2023-02-17
- /2012/07/dont-block-on-async-code.html2 people · 2 mentions · first linked 2014-11-07
- /2012/02/async-and-await.html2 people · 2 mentions · first linked 2019-01-29
What Hacker News says?
How about BlockingCollection<T>? If I understand it correctly you can even have select like sementics with BlockingCollection.TakeFromAny(...) Edit: Sorry, messed it up a little bit. BlockingCollection will block your current thread for any other computation and does not allow to await on it. But there seem to be alternatives: http://stackoverflow.com/questions/21225361/is-there-anythin... http://blog.stephencleary.…
Comment linking /2012/12/async-producer-consumer-queue-3-more.html
on “Microsoft takes .NET open source and cross-platform”Submitted There is no Thread (2013) as a story · 1 points
HN discussionIf you don't know what a thread is, start there. Otherwise, you might read this. https://blog.stephencleary.com/2013/11/there-is-no-thread.ht...
Comment linking /2013/11/there-is-no-thread.html
on “Things that used to be hard and are now easy”Submitted Recursive (Re-Entrant) Locks (2013) as a story · 1 points
HN discussion> I must be dumb Nope, async really isn't trivial. > I know .await != join_thread(), but doesn't execution of the current scope of code halt while it waits for the future we are `.await`-ing to complete? It doesn't, that's the charm of it. It's best to treat 'await' as syntactic sugar, and to dig in to the underlying concepts. I realise we're not talking C#/.Net, but that's what I know: in .Net, your function might…
Comment linking /2013/11/there-is-no-thread.html
on “Async-std: an async port of the Rust standard library”Submitted Implementing GCC's Builtin Functions as a story · 1 points
HN discussion> Sooner or later, in anything built with a computer, there's going to be polling. ... But under the hood, there's polling. Is that true? I am reminded of this essay that goes into a deep dive of what happens under the hood with http and the underlying network I/O https://blog.stephencleary.com/2013/11/there-is-no-thread.ht... And at the lowest level, the network card interrupts the CPU because it has finished readi…
Comment linking /2013/11/there-is-no-thread.html
on “Message DB: Event Store and Message Store for PostgreSQL”Submitted Docker as a Tool Provider as a story · 1 points
HN discussion> var myValue = DoSomethingAsync().ConfigureAwait(false).Result; Came out a decade ago and we still don't know how to use it safely. This example doesn't compile because there is no Result on ConfiguredTaskAwaitable. Regardless, ConfigureAwait(false) does absolutely nothing here because this Task is not being awaited. If you're going to block this thread, you must push the work to another thread or it's going to dea…
Comment linking /2012/07/dont-block-on-async-code.html
on “Asynchronous Programming in C#”Submitted There is no thread (2013) as a story · 1 points
HN discussionNo, I mean that yielding allows more requests to be executed at the same time on the same number of threads, increasing throughput. Overhead of context switches is not that relevant, this is are small fry compared to e.g. waiting 100s of milliseconds (or more) for a DB or API. Yielding instead of busy-waiting, as I said above, allow another request that is ready to execute to do so sooner. This leads to higher throu…
Comment linking /2013/11/there-is-no-thread.html
on “Asynchronous Programming in C#”Submitted There is no thread (2013) as a story · 1 points
HN discussionI have been a C# developer for a while as well now and I'm not sure if this is true: "Use of async void in ASP.NET Core applications is ALWAYS bad. " Depending on the context, it can even be recommended to do async void. See Stephen Cleary's brilliant explanation of this: https://blog.stephencleary.com/2012/02/async-and-await.html Edit: The correct link is this, see first table column exceptions: https://docs.micros…
Comment linking /2012/02/async-and-await.html
on “Asynchronous Programming in C#”Submitted There are no threads in async as a story · 1 points
HN discussionIt's .NET focused but this FAQ[0] (2009) has good general advice regarding things like message framing and detecting dropped connections. [0]: https://blog.stephencleary.com/2009/04/tcpip-net-sockets-faq...
Comment linking /2009/04/tcpip-net-sockets-faq.html
on “A TCP/IP Tutorial (1991)”C# has threads but async/await does not use them. If you think that `async` in C# does the same thing as `@spawn` in Julia and `go` in Go, you are mistaken. It does not. There is also an `@async` macro in Julia that does what the `async` keyword in C# does (which, again, does not involve threads). https://stackoverflow.com/questions/37419572/if-async-await-... https://blog.stephencleary.com/2013/11/there-is-no-threa…
Comment linking /2013/11/there-is-no-thread.html
on “Composable multi-threaded parallelism in Julia”Yeah, I should clarify what I was saying. I wasn't calling Task.Run(), but I was doing: for (var i = 0; i < 1000000; i++) { var unused_task_var = RunTaskAsync(); } await RunMainMonitoringTaskAsync(); And I purposefully wasn't calling await on "unused_task_var". And this was doing what I wanted, running all those tasks on multiple background threads in the pool, as long as RunTaskAsync method itself yielded once earl…
Comment linking /2012/02/async-and-await.html
on “Memory usage of a toy C# server and client with 500K concurrent connections on”This is a good article which tries to explain how .NET works under the hood. https://blog.stephencleary.com/2013/11/there-is-no-thread.ht...
Comment linking /2013/11/there-is-no-thread.html
on “Memory usage of a toy C# server and client with 500K concurrent connections on”Does it? https://blog.stephencleary.com/2013/11/there-is-no-thread.ht...
Comment linking /2013/11/there-is-no-thread.html
on “Memory usage of a toy C# server and client with 500K concurrent connections on”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-steali…
Comment linking /2012/07/dont-block-on-async-code.html
on “Java at 30: Interview with James Gosling”Hey, so my my career path has been C# (many years) -> F# (couple years) -> Clojure (3 months). I understand multithreading primarily through the lens of async/await, and have been having trouble fully grokking the Clojure's multithreading. One of the commandments of async/await is don't block: https://blog.stephencleary.com/2012/07/dont-block-on-async-c... Which is why the async monad tends to infect everything. Clo…
Comment linking /2012/07/dont-block-on-async-code.html
on “Six Years of Professional Clojure”There is some overhead in thread management, yes. But in a server scenario (e.g. a web api) there is already thread management happening, as it all runs in threads from a thread pool. I don't believe that you pay a significant additional cost per await - i.e. if you have one await in your code, then you might as well use as many as you can to chop the operation up into small parts so that operations can flow through…
Comment linking /2013/04/ui-guidelines-for-async.html
on “Common Multithreading Mistakes in C# – Unsafe Assumptions”Disagree, async ( edit: in .Net at least) is pretty complex. For instance, from my experience it seems few C# programmers know that it's possible to deadlock if you get it wrong. [0][1] Plenty of people get confused with the basics, too. [2][3] [0] https://blog.stephencleary.com/2012/07/dont-block-on-async-c... [1] https://docs.microsoft.com/en-us/archive/msdn-magazine/2013/... [2] https://stackoverflow.com/a/346811…
Comment linking /2012/07/dont-block-on-async-code.html
on “Zig 0.7.1 Released – 69 bugs fixed”This is basically "There is no Thread": https://blog.stephencleary.com/2013/11/there-is-no-thread.ht... There are times when you can offload an asynchronous task to non-CPU hardware, in which case the blocking thread can disappear. The thread reappears when the hardware asynchronously informs the CPU of task completion. (This idea is what Node.JS is entirely reliant upon.) Consider if we didn't have timing hardware…
Comment linking /2013/11/there-is-no-thread.html
on “Why Threads are a Bad Idea (for most purposes) (1995) [pdf]”Async/Await does not imply multiple threads. Often, the async version will use fewer threads than the equivalent synchronous code. http://blog.stephencleary.com/2013/11/there-is-no-thread.htm...
Comment linking /2013/11/there-is-no-thread.html
on “What lies beneath async/await in C#?”You've mentioned an abstraction but not explained why it's leaky. I agree that async/await leaks in places, such as in the surprising deadlocks that Stephen Cleary explains. I've met more than one pretty serious C# developer that wasn't aware of this. http://blog.stephencleary.com/2012/07/dont-block-on-async-co... > the question is whether it is part of the API and explained or not More broadly it's a question of pr…
Comment linking /2012/07/dont-block-on-async-code.html
on “Postgres indexes under the hood”There's terrible dangers that await one who casually throws .Result or .Wait() into an existing ASP.NET application. The intersection between synchronous and asynchronous code is the ugliest. The most dangerous is how deadlocks can arise because of the execution context of a running application vs the execution context of your unit tests. If you're already in .NET Core, you're probably fine. For more, try https://de…
Comment linking /2012/07/dont-block-on-async-code.html
on “Network.framework: A Modern Alternative to Sockets (2018)”Yep! The async model in node.js is very similar. Here's a fantastic blog post about the details of it all: http://blog.stephencleary.com/2013/11/there-is-no-thread.htm...
Comment linking /2013/11/there-is-no-thread.html
on “C# 6.0: An Introduction”This is great and despite what the article says, an actually useful technique. The reason this performs well is the .NET runtime does monomorphization when the generic type parameters are value types (primitive types like int or user-defined structs). In modern .NET you would use static abstract methods interface methods to implement this feature. But if you have to run on the old Windows-only .NET Framework, you ne…
Comment linking /2022/10/modern-csharp-techniques-3-generic-code-generation.html
on “BrainFlood: Runtime code generation via reflection in .NET”Although it seems async/await is based on multiple threads, this is not the case. To learn about this, read this blog post: https://blog.stephencleary.com/2013/11/there-is-no-thread.ht... Please let me know what you think.
Comment linking /2013/11/there-is-no-thread.html
on “Async await: the worst thing to happen to programming?”