3 ms·
I don't understand what you mean. What is to say that an async-fn is not long running? It can just as well consume a thread, right?
by bruce343434 5y ago
I don't understand what you mean. What is to say that an async-fn is not long running? It can just as well consume a thread, right?
- lijogdfljk 5y agoI may not follow you - but to expand what _(i believe)_ the GP comment said; any long running code - say a loop that spins for an hour, is bad in the async context, because that async thread is part of the runtime. Better to take those special cases and let the executor move the computation to a dedicated thread. At my work i mix a lot of compute heavy work in an async context, and if i let this compute heavy stuff run on my async threads i'd potentially starve my runtime. Tasks wouldn't get woken up on time, etc.
- bruce343434 5y agoright, but this isn't an argument against allowing arbitrary async expressions. I can make an async-fn that runs an infinite loop just as easy.
- lijogdfljk 5y agoThat's the point though - anything blocking the async thread is bad. If your loop is going to run for an hour, you'd put arbitrary yield points in it so that the executor can reliably call other tasks
- jayd16 5y agoWell I can only speak to C# really but... The preferred pattern is to avoid long running tasks in the default thread pool as it's a shared resource. Long running tasks should be executed somewhere else, either some new thread pool or just a new thread or just don't use async and make it your caller's problem. The point is that you don't want to consume the limited shared resource. In your case, what would happen? Would a new thread be created? Is it ok to use the default pool? Did the synchronous method writer even consider this? It's hard to say. Now, does this need to be enforced by the language? No. Developers could simply append "_Async" to make it clear a method can be put on the default thread pool or not. That's still a form a coloring though. Even if you consider it a choice by the caller, it's still a color that needs to be determined and you never want to exhaust your default thread pool. That said, there are other reasons why calling an async method should have different semantics than calling a normal sync method. Just saying that the "can use shared threads" aspect of async methods can probably live as a convention.
- Groxx 5y agoasync things are (generally) cooperatively executed/scheduled/etc. they choose when to give up control and allow other things to run (`await x`). this is in contrast to threads / processes, which are done preemptively - the OS can say "stop doing that, do this", swap out the memory, and your thread basically can't do anything about it. (which is why there are thread priorities) normal synchronous code never gives up control until it's done. so it'll block the cooperative/async scheduler until it finishes, whether it's maxing out the CPU or just waiting idly for a network request to respond. if there's anything else happening on that scheduler, it has to wait, which can lead to rather terrible behavior. and last but not least: you generally cannot move async code between threads. async tends to imply you want same-thread concurrency guarantees, to avoid the cost of cross-thread mutexes and whatnot. so while you could in theory just interrupt an async scheduler and move it to a new thread, in practice that's not usually safe, so it isn't done. you could build a system that allows jumping between threads though - that's essentially what green threaded languages do under the hood (like Go). which gives you a middle-ground of "nice thread-like semantics" but "nice async performance", but neither quite as good as a pure system in sometimes-important edge cases. --- all that said, yes, you can just dedicate a thread to a single scheduler, run a synchronous func on it, and it has practically no additional cost over using a normal thread. but you have to choose to do that, it won't happen by default.