3

Is it possible to define and call method asynchronously in the same thread as the caller? Suppose I have just one core and I don't want threading management overhead with like 100 threads.

Edit The reason I ask is nodejs model of doing things - everything on one thread never blocking anything, which proved to be very efficient, which made me wonder if same stuff possible in C# (and I couldn't achieve it myself).

Edit2 Well, as noted in comments node isn't single-threaded after all (however simple load test shows, that it uses just one core...), but I think what makes it so efficient is implicit requirement to write only non-blocking code. Which is possible in C#, except not required:) Anyway, thanks everyone...

More info in this SO post and even more in this one

Community
  • 1
  • 1
ren
  • 3,843
  • 9
  • 50
  • 95
  • What's the point of `async` if it's not in a different thread? Why would that be any better than serial execution? – Matt Ball Apr 27 '13 at 18:34
  • 6
    @MattBall: Suppose the asynchronous operation is not CPU bound. Suppose the asynchronous operation is, say, wait thirty seconds and then reset the color of the button. Why should that have to spin up another thread? – Eric Lippert Apr 27 '13 at 18:35
  • 7
    @ren: That said, Matt Ball has a point. Whether the operation in question needs to run on another thread or not is up to the implementer of that operation. If you want to limit the number of threads created, that's what the thread pool is for. If you spawn an asynchronous task, the TPL will take care of scheduling the right number of threads from the pool to saturate the core. Rather than have us continue to guess what you're doing, how about you ask a question about the *actual problem* you have instead of proposing a solution. – Eric Lippert Apr 27 '13 at 18:37
  • @EricLippert Well, yes, but that still has overhead, which in principle isn't necessary. I'm just looking at nodejs/javascript, where they do everything in one thread which is possible since everything is async – ren Apr 27 '13 at 18:42
  • 4
    If your question is "can I write a program where every operation is asynchronous and every operation is on the same thread?" then the answer is yes, of course you can do that. If **you** are the person writing the asynchronous operation then **you** decide what thread it goes on. If your question is "I have this method ComputeFractalAsync that uses a thread-pool thread and I want it to run on the current thread" then call up the person who wrote that method and ask them to write you a version that doesn't use the thread pool. – Eric Lippert Apr 27 '13 at 18:48
  • @EricLippert My question is the first one, where I write everything, and some simple example of how to do that would be nice! (that is how do I put it on the same thread as caller's). Sorry for little detail, I'm just investigating here. – ren Apr 27 '13 at 18:51
  • This is one of the reasons why I like TPL: It takes away the worry about thread(overhead) and makes me think about (logical) jobs/tasks. By leaving the number of threads to be decided at run-time instead of development-time the application will use the available hardware in a better way than I can predict (in most cases). – Emond Apr 27 '13 at 18:56
  • 1
    nodejs is not entirely single-threaded. the js is actually synchronized into event functions, so you don't see the multi-threading. Also read [Is NodeJS really Single-Threaded?](http://stackoverflow.com/questions/7018093/is-nodejs-really-single-threaded) and [Node is Not Single Threaded](http://rickgaribay.net/archive/2012/01/28/node-is-not-single-threaded.aspx). – metadings Apr 27 '13 at 19:21
  • 3
    If you want all the calls to be on the same thread and you're writing all the code then **never create a new thread**. Simple as that. – Eric Lippert Apr 27 '13 at 21:37

1 Answers1

9

It's not really clear exactly what context you're talking about, but the async/await feature of C# 5 already helps to support this sort of thing. The difference is that whereas in node.js everything is forced to be single threaded by default (as I understand it; quite possibly incorrectly given the links in the comments), server-side applications in .NET using asynchrony will use very few threads without limiting themselves to that. If everything really can be served by a single thread, it may well be - if you never have more than one thing to do in terms of physical processing, then that's fine.

But what if one request comes in while another is doing a bit of work? Maybe it's doing just a small amount of encryption, or something like that. Do you really want to make the second request wait for the first one to complete? If you do, you could model that in .NET fairly easily with a TaskScheduler associated with a single-thread thread-pool... but more commonly, you'd use the thread-pool built into .NET, which will work efficiently while still allowing concurrency.

First off, you should make sure you're using .NET 4.5 - it has far more asynchronous APIs (e.g. for database and file access) than earlier versions of .NET. You want to use APIs which conform to the Task-based Asynchronous Pattern (TAP). Then, using async/await you can write your server-side code so that it reads a bit like synchronous code, but actually executes asynchronous. So for example, you might have:

Guid userId = await FetchUserIdAsync();
IEnumerable<Message> messages = await FetchMessagesAsync(userId);

Even though you need to "wait" while each of these operations talks place, you do so without blocking a thread. The C# compiler takes care of building a state machine for you. There's no need to explicitly write callbacks which frequently turn into spaghetti code - the compiler does it all.

You need to make sure that whatever web/web-service framework you use supports asynchrony, and it should just manage the rest, using as few threads as it can get away with.

Follow the two links above to find out more about the asynchrony support in C# 5 - it's a huge topic, and I'm sure you'll have more questions afterwards, but when you've read a bit more you should be able to ask very specific questions instead of the current broad one.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • For multithreading I really like to recommend Joseph Albahari's [Threading in C#](http://www.albahari.com/threading/) – metadings Apr 27 '13 at 19:28
  • 7
    @metadings: That's certainly a great tutorial - but a lot of it is largely irrelevant in an async world where you don't need to explicitly start new threads or even new tasks most of the time. Asynchrony and concurrency are certainly related, but not the same thing. – Jon Skeet Apr 27 '13 at 19:46