
Ask HN: What are your thoughts on C# on Linux? - totalperspectiv
It&#x27;s in the same space as Java&#x2F;Go, and .Net Core seems to be getting a lot of love on Linux. The recent 3.0 announcement shows some awesome performance gains and some sweet new features, including ready to run to reduce startup time, and moves toward AOT &#x2F; single binary (although coreRT already does this?).
======
balfirevic
I have been working with C# for a long time now, so it's pretty cool to watch
it become a contender in cross platform server-side development (Mono has been
there for some time now for desktop stuff, but I don't know how much traction
it got. I don't think many people used it for back end work).

I think the language is really well-designed. It does have a lot of features,
but still feels pretty coherent and not overwhelming. LINQ is great. As for
what's coming, I'm particularly excited about the non-nullable types in C#
8.0.

I wish it would get low syntactic overhead sum types, similar to Haskell,
OCaml and F#. That's the biggest thing I currently miss.

One thing I am disappointed in is going with async/await paradigm instead of
supporting green threads. This essay explains why pretty well, and has already
been linked on HN a few times:
[https://journal.stuffwithstuff.com/2015/02/01/what-color-
is-...](https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-
function/)

~~~
rndgermandude
To be fair, in C# a function can "opt out" of async-await with
Task<T>.Wait()/.Result/.GetAwaiter().

In a way C# will use a mixture of green-ish threads/threads already, in that
await-ed calls are either scheduled on a thread worker pool (via a
TaskScheduler) or executed synchronously ("inline")... Which comes with it's
own set of surprises and gotchas.

    
    
        async Task<bool> DoSomethingElse() {
          // [0] do something long-running
        }
        async Task DoSomething() {
          var otherTask = DoSomethingElse();
          // [1] do something long-running
          var other = await otherTask;
          if (other) {
            // do yet another thing
          }
        }
    

So, when will [1] run? Before [0], concurrently on another pool thread to [0],
or after [0]? The answer is: you cannot really know from the information
presented. The compiler might decide that DoSomethingElse is to be called
synchronously ("inline", attached child tasks), so before [1] will get a
chance to run. Or it might decide to run it concurrently, but then the
TaskScheduler might decide it's doing enough of concurrent work already (e.g.
every thread in the pool is busy) and run [1] before [0].

This is usually nothing to be concerned about, until it is. Coming from js'
world of async-await where a certain order is guaranteed, I footgunned myself
in C#... my real-world DoSomethingElse() essentially was a forever-loop that
would only terminate on a CancelationToken (basically a "is this canceled"
flag) and the compiler decided it should be executed synchronously for me, so
[1] never got a chance to run. The fix was Task.Run(DoSomethingElse) btw, thus
explicitly not "inline"-ing the call.

[https://docs.microsoft.com/en-us/dotnet/standard/parallel-
pr...](https://docs.microsoft.com/en-us/dotnet/standard/parallel-
programming/attached-and-detached-child-tasks)

------
PaulHoule
C# is a fine language and it has had traction off the Microsoft platform for a
long time.

For instance, many games for the PS(3|4| Vita) are written with something
called the PhyreEngine which is based on .NET and lets you make pro-quality
games that are portable across those platforms, the PC, and some other
platforms too.

~~~
totalperspectiv
The Unity ecosystem also seems pretty sweet. Especially the new Burst
compiler.

------
rndgermandude
C# is my new python: batteries included + Nuget, but faster and properly typed
with LINQ sugar on top. What is missing is a great http library, tho the
batteries-included stuff usually is enough although a bit clunky.

~~~
EnderMB
Have you played with RestSharp at all? I tend to stick with the standard
library in .NET, but a lot of people swear by RestSharp.

~~~
rndgermandude
Played with yes. And it makes things less clunky, indeed. But it's still built
on top of System.Net.HttpWebRequest, meaning it inherits its limitations too,
like e.g. sub-par http(s)-only proxy support.

------
gtsteve
I've been deploying production .NET apps on Linux in Mono and NetCore for a
few years now- Core is vastly superior to Framework even if you're not
targeting Linux.

We target netcoreapp2.2 and execute the binary by using the dotnet tool pre-
installed in containers but you can also just output a binary that can be
executed standalone in your chosen platform.

I was able to set up a build agent for CI in a couple of hours; you really
only need the SDK and you don't need to go through painful guesswork about
what you need to install or copying targets that only exist in the desktop
version of Visual Studio or stuff like that.

Also, you don't need to tangle with various runtimes and their licenses (like
Java) because there is only one and Microsoft seem to only be interested in
monetising their development tools, operating systems and cloud offerings.

I would not have believed you if you told me 5 years ago that C# development
could be this good. I could not possibly imagine targeting another language
(with the possible exception of front-end code and perhaps front-end web apps)

