Live data from Hacker News

Asynchronous Programming in C#

github.com

51–60 of 186 posts

Re: Asynchronous Programming in C#

#51

Earlier quoted context omitted.

Database operations should be async, you shouldn't consume them synchronously, as they do IO. Async/Await came out in 2012, almost a decade ago (and with great first party library support, I might add). Moralizing aside, sometimes you do want to call async APIs as synchronous code. I don't think there should be a synchronous version of the API implemented as well, you just need to do var myValue = DoSomethingAsync().…

"var myValue = DoSomethingAsync().ConfigureAwait(false).Result;" In my view there should be a built-in keyword to do this right. It's too easy to get this wrong and even worse possible problems only show up rarely.

Well, you can put it into an extension method like this:

T SyncResult(this Task task){ return task.ConfigureAwait(false).Result; }

Same for ValueTask. It may already be implemented in the base .NET library as well.

Re: Asynchronous Programming in C#

#52

Earlier quoted context omitted.

Database operations should be async, you shouldn't consume them synchronously, as they do IO. Async/Await came out in 2012, almost a decade ago (and with great first party library support, I might add). Moralizing aside, sometimes you do want to call async APIs as synchronous code. I don't think there should be a synchronous version of the API implemented as well, you just need to do var myValue = DoSomethingAsync().…

"var myValue = DoSomethingAsync().ConfigureAwait(false).Result;" In my view there should be a built-in keyword to do this right. It's too easy to get this wrong and even worse possible problems only show up rarely.

The reason there isn't a keyword is because its not possible to do it right. The example given is far from foolproof.

Re: Asynchronous Programming in C#

#53
post #14

C# was my first exposure to async/await back in 2015 and I initially had trouble wrapping my head around various details (i.e. ConfigureAwait etc.). I think the languages that have done best job in removing all that detail are Go and Elixir (Beam based languages). Which if you pay attention removed the overhead of rewiring your brain to do async/await all the way down. I repeated async/await systems recently with Kot…

Yeah, I don't like Go in most respects, but their approach to concurrency is way more intuitive than async/await. That said, Go doesn't have any standard promise or futures libraries, which is quite ridiculous. Yes, you can roll your own or go get one, but that is something basic should be in the language.

Re: Asynchronous Programming in C#

#54
post #53
post #14

C# was my first exposure to async/await back in 2015 and I initially had trouble wrapping my head around various details (i.e. ConfigureAwait etc.). I think the languages that have done best job in removing all that detail are Go and Elixir (Beam based languages). Which if you pay attention removed the overhead of rewiring your brain to do async/await all the way down. I repeated async/await systems recently with Kot…

Yeah, I don't like Go in most respects, but their approach to concurrency is way more intuitive than async/await. That said, Go doesn't have any standard promise or futures libraries, which is quite ridiculous. Yes, you can roll your own or go get one, but that is something basic should be in the language.

As someone who has never really used promises or futures, what do they add, or how do they make concurrent programming easier or clearer than what's currently in Go?

Re: Asynchronous Programming in C#

#55
post #41
post #14

C# was my first exposure to async/await back in 2015 and I initially had trouble wrapping my head around various details (i.e. ConfigureAwait etc.). I think the languages that have done best job in removing all that detail are Go and Elixir (Beam based languages). Which if you pay attention removed the overhead of rewiring your brain to do async/await all the way down. I repeated async/await systems recently with Kot…

I think it's clear from the languages given that the added complexity is to handle UI workflows, no?

You can have UI workflows just as well with a language that has (runtime-managed) green threads, like Go and Elixir. It's just that you sometimes have to make sure that certain green threads have their actions scheduled on the UI (OS) thread for backwards compatibility reasons. For example, the Scala ZIO library provides the means to control where (on which OS thread) code is scheduled in a very intuitive way that does not involve ConfigureAwait hacks. ZIO is not green threads and rather more like async/await, but a similar approach could be implemented in languages with runtime-managed green threads as well.

Re: Asynchronous Programming in C#

#56

Earlier quoted context omitted.

In a vacuous sense, but in practice you almost always use asynchronous code to achieve concurrency. The canonical Microsoft tutorial on async spends about half its time talking about hiw to make your code concurrent to take advantage of async. https://docs.microsoft.com/en-us/dotnet/csharp/programming-g...

Concurrency does not require multi-threading. Maybe you mean parallelism? Concurrency can still be really valuable in the context of a single threaded application.

If a program wants to perform a task in an async way without delegating it to an external program (like a database server or the OS' I/O system), it has to use threads, right? I think the point is that concurrency, for some tasks, basically requires multithreading. Not for the parallelism benefits, but just to be able to make concurrency possible for a task that requires blocking a thread.

Re: Asynchronous Programming in C#

#57
post #14

C# was my first exposure to async/await back in 2015 and I initially had trouble wrapping my head around various details (i.e. ConfigureAwait etc.). I think the languages that have done best job in removing all that detail are Go and Elixir (Beam based languages). Which if you pay attention removed the overhead of rewiring your brain to do async/await all the way down. I repeated async/await systems recently with Kot…

It's kind of odd that JetBrains chose async/await for Kotlin considering the JVM is going towards the Go approach for virtual threads. I guess they had to since they wanted to support android/js?

Re: Asynchronous Programming in C#

#58

The sync over async issue is a real common problem for me when trying to get a large older codebase converted to async and you can't just do it all at once. You still need support non async callers and you want to share code between the new async version and the old sync versions it makes it really difficult to do so. Say you have a db layer you want to move to async but you still have to support a sync api over that…

Database operations should be async, you shouldn't consume them synchronously, as they do IO. Async/Await came out in 2012, almost a decade ago (and with great first party library support, I might add). Moralizing aside, sometimes you do want to call async APIs as synchronous code. I don't think there should be a synchronous version of the API implemented as well, you just need to do var myValue = DoSomethingAsync().…

Some things simply don't have an async API at the low level, e.g. DNS lookup: there is no asynchronous version of getaddrinfo(3). So if you look at the .NET sources, you'll see that Dns.GetHostEntryAsync pushes a task to a thread pool that calls getaddrinfo(3).

In the end, you arrive at a "sync top-level APIs -- async library APIs -- sync low-level OS APIs" sandwich of dubious efficiency.

Re: Asynchronous Programming in C#

#59

Earlier quoted context omitted.

Database operations should be async, you shouldn't consume them synchronously, as they do IO. Async/Await came out in 2012, almost a decade ago (and with great first party library support, I might add). Moralizing aside, sometimes you do want to call async APIs as synchronous code. I don't think there should be a synchronous version of the API implemented as well, you just need to do var myValue = DoSomethingAsync().…

"var myValue = DoSomethingAsync().ConfigureAwait(false).Result;" In my view there should be a built-in keyword to do this right. It's too easy to get this wrong and even worse possible problems only show up rarely.

If this really needs to happen then I like .GetAwaiter().GetResult() instead of .Result to get the same exception behavior as await rather than the wrapped AggregateException that .Result throws. This is especially helpful if DoSomethingAsync sometimes throws synchronously rather than returning a task.

Re: Asynchronous Programming in C#

#60

The sync over async issue is a real common problem for me when trying to get a large older codebase converted to async and you can't just do it all at once. You still need support non async callers and you want to share code between the new async version and the old sync versions it makes it really difficult to do so. Say you have a db layer you want to move to async but you still have to support a sync api over that…

Database operations should be async, you shouldn't consume them synchronously, as they do IO. Async/Await came out in 2012, almost a decade ago (and with great first party library support, I might add). Moralizing aside, sometimes you do want to call async APIs as synchronous code. I don't think there should be a synchronous version of the API implemented as well, you just need to do var myValue = DoSomethingAsync().…

To avoid deadlocks, you don't need the ConfigureAwait(false) here, but you do need it to have been applied correctly in all the async code you're calling.
Post reply on HN