120 comments

[ 2.9 ms ] story [ 194 ms ] thread
I wonder if it was on purpose or accident that the LTS release of .NET Core coincides with the LTS release of Ubuntu...
What do the two have to do with each other? I'd say it's a coincidence, I don't think MS is trying to steal Canonical's thunder or anything.
No relationship to the 18.04 LTS, but we were following that release closely. We started testing on 18.04 at the start of the year, and offering Docker images for it at around the same time. We're also watching the Alpine 3.8 release closely.
Any chance .NET Core is going to be supported on FreeBSD/NetBSD/OpenBSD in the near future?
FreeBSD was the first community port, but vanished again. Seem like lack of size of the community interst there.
Anxious to finally play with this, been wanting the full library/stack update for span<t>/memory<t> to get a feel for actually using them to optimize code.
I've been moving some libraries over from T[] to Memory<T> and Span<T>.

I've found it's a little tricky to get used to calling Slice() all the time. But it opens up so many doors for allocation reduction and perf improvement.

Also, it is so nice to not have to pass (array, offset, length) around everywhere

This is a landmark release for .NET.

The most important since at least framework 4.0 maybe even 3.0.

We are getting:

- Span<T>/Memory<T> : A 0-copy, unified way of accessing Managed or Unmanaged memory.

- Channel<T> : High performance thread-safe queues (like go channels)

- Pipelines : an async, 0-copy version of Stream

- In-box support for Array/Buffer pooling (finally!) (MemoryPool, ArrayPool)

- Better primitives for pointer manipulation and memory marshaling. (MemoryMarshal)

- New primitives for high performance parsers and formatters (System.Buffers.Binary and System.Buffers.Text)

- Improved support for SSE/NEON via Vector<T>

- Microsoft.Windows.Compatibility : Windows specific APIs on .NET Core (Registry, EventLog, NamedPipes...)

- Tiered Compilation

- Faster tooling

- Wider Platform support

If you write code on .NET, you should [Edit] evaluate this release with to see if it fits your business needs [/Edit]

Doubly so if you care about runtime performance.

Where can I find out more about Channel<T>? I've been googling but it's hard to find anything (especially as Channel 9, and old WCF channels comes up a lot in the results).
The Docs on Channel<T> are currently lacking :(

But it is pretty simple to use. It is in nuget package "System.Threading.Channels".

You basically call Channel.CreateBounded<T>(int) to create a channel that will buffer a limited number of T objects.

A Channel has a ChannelReader and ChannelWriter which are two ends of the same channel. The reader is the output side, the writer is the input side.

Each side exposes methods to synchronously try to Read or Write or asynchronously Read or Write (respectively).

It supports "Completion" meaning that the Writer can signal the Reader(s) that it is done writing forever. For example imagine you had a channel that was for Log Messages. A bunch of readers might be listening, but then the App shuts down. The writer can call "Complete()" on the channel and the Readers will get wake up and get a message that there is no more messages and flush themselves and shut down.

As a note you will need to run your own processing thread to await messages from the channel. Unlike Dataflow which will span it's own taks to handle messages.

I will write up an example Gist and reply to this thread in a little bit.

Other notes: - The API is very similar to Dataflow since Stephen Toub wrote them both. - It is extremely fast. I have seen > 1.25M messages per second in my benchmarks. - It is mostly allocation free due to using the new ValueTask<T> which is a struct

Futher Reading: https://www.nuget.org/packages/System.Threading.Channels/ https://apisof.net/catalog/System.Threading.Channels

What's the difference between this and the BlockingCollection<T>? Aside from being async-friendly it looks pretty similar. You can have a bounded collection with limited size, and completing the writes looks similar too - collection.GetConsumingEnumerable() responds the same way.
Good question. BlockingCollection is actually a wrapper around a ConcurrentQueue. It provides some nice things like....blocking so the queue can be used in a producer/consumer manner.

Channels does this but has 2 advantages.

1. It is built on the most up-to-date threading primatives (ValueTask) which gives it a perf advantage.

2. It's internal design is very simple and lightweight. BlockingCollection was designed to have swappable guts. Channels are single purpose.

The other nice thing is the channels API is really no nonsense super simple to get GREAT performance out of normal async/await. No tuning really needed. I got >300Krps out of a sequence of chained channels with a buffer size of 1.

> If you write code on .NET, you should adopt this release ASAP.

That really depends what classes you use. There are still a lot of classes that haven't been implemented in .Net Core and many of them supposedly won't be implemented. Others were re-implemented and renamed and might not match features. You'll want to move to .Net Core eventually, but not every .Net release is going to be easy to move. Moving from .Net Framework to .Net Core is like moving from .Net Framework to mono. It's mostly similar, but it's still wholly different and not intended to be a 100% drop in replacement.

The Microsoft.Windows.Compatibility namespace isn't new at all. At least that's what the Windows Compatibility Pack for .Net Core [0] used at the end of 2017. It looks like it might just finally be out of the preview stages.

[0]: https://blogs.msdn.microsoft.com/dotnet/2017/11/16/announcin...

is Span<T>/Memory<T> and Channel<T> supported for use in F#?
Uhh, Span/Memory support is coming soon https://github.com/fsharp/fslang-suggestions/issues/648

Channel<T> uses ValueTask<T> which is kinda painful in F# for now.

https://github.com/fsharp/fslang-suggestions/issues/581

It's a little sad to hear that this wasn't considered part of MS core effort for the 2.1 rollout. I think the challenge is C# is viewed as 'good enough' with incremental language improvements, while F# gets dragged behind via support from the community (although dedicated, they are not large). I'm wondering if this situation will ever change. I already know of companies sceptical of adopting F# because of lack of perceived commitment by MS.
I feel your pain. F# has effectively been punished for being so innovative.

They had tuples, async/await, and match statements a decade ago and every time C# adopts one of their feature they change the implementation and make F# retool. It's kinda awful.

At this point I want F# to do a hard reset, rebuild on top of Roslyn, natively adopt ValueTuple and Task/ValueTask then grow alongside C# like VB tried to.

> At this point I want F# to do a hard reset, rebuild on top of Roslyn, natively adopt ValueTuple and Task/ValueTask then grow alongside C# like VB tried to.

I've been hoping for basically the same thing. That said, putting any new language on top of Roslyn (not just using it for IL generation, but actually making it a proper provider a la C#) is 1) not supported, and 2) not seeming like it's going to be. I have a language on .NET that I would love to build into a first-class Roslyn provider but there just isn't any support for that right now. Maybe F# folks inside MS can work to change that.

C# has a large network effect and it also has very few disadvantages, so there is little motivation to switch to F# for C# devs.
C# does keep getting better, and making the delta between what it offers and what F# offers smaller, at least from what I can see. I've really wanted to get on the F# train, but I just haven't been able to get it out of the station yet.

I'm somewhat astounded that VB.Net is still a thing, however.

F# always suffered from lack of VS tooling support, I was always on the edge waiting for it to be supported on GUI designers just like VB.NET and C#.

Using it mostly for scripting like tasks only.

Then it wasn't relevant for .NET Native support, and finally Microsoft keeps ignoring some vocal anti-MS/C# members in the community, which made me loose any remaining interest.

I rather have C# with some FP like features, than a FP language without tooling support and needless forum discussions.

Regarding VB.NET, it is used quite a lot in some enterprise shops.

I have seen many apps that started as office macros and eventually grew up to be VB.NET ones.

Even if VB.NET is more complex than VB was, it still easier than C# for those office employees that know one or two things about coding.

> If you write code on .NET, you should adopt this release ASAP. Doubly so if you care about runtime performance.

I care about performance, but:

Still have customers on .NET 4.0.

.NET Core 2.1 doesn't do EF6, Forms or WPF, need to wait for 3.0 for that.

Not all third party libraries are already on Core.

Given all that, Core 2.1 is full of goodies that I will surely play around with.

Yeah, our clients are on Framework I feel your pain.

...But reading between the lines, you probably still have clients on XP (.NET 4.0). That's gotta sting. We made a fuss about TLS1.2 support being required and forced them to upgrade to Win7/.NET 4.5.2 at least.

I have gotten gotten a smallish winforms app to work with the new .csproj format. But it's painful. WPF is probably a nightmare.

As an aside if you make it to .NET 4.5+ and get async/await. It works great with winforms and presumably WPF!

You can get async/await on .NET 4.0 using Microsoft.Bcl.Async
Kind of, it has some issues if you try to use it with Forms.
Yep it was something that started on XP and transitioned to 7.

Nope, we cannot make it to .NET 4.5+ due to some third party libraries, which is a bummer, because we are stuck with BackgroundWorker as TPL had some bugs with Forms on 4.0, which were only fixed on 4.5.

It is only one project thought, the other issue are the IT upgrade policies regarding developer images.

> Still have customers on .NET 4.0.

Note that you don't have to install netcore on machines, you can create self-contained releases[1].

> EF6, Forms or WPF

Depending on your architecture you may be able to upgrade to netcore piecewise (i.e., microservices over "dumb" protocols like HTTP or gRPC). We are currently turning our monolith into microservices; porting to netcore where possible (using an anti-corruption layer where not). We've only just started but are already reaping benefits.

[1]: https://docs.microsoft.com/en-us/dotnet/core/deploying/#self...

I am against microservices versus doing modular architectures, once upon a time they were called SUN-RPC, DCOM, CORBA, SOAP, RMI, Remoting, WCF... so I do have quite some experience in "microservices".

For native GUI applications it is nothing than a waste of resources.

Three tier architectures with modular designs across several assemblies are a much better solution, no need to go after what is cool.

The EF6, Forms and WPF support is the major goal of .NET Core 3.0, so why should I ask our customers to waste money with microservices and application rewrites?

The things you are pointing out are orthogonal to the architectural tactic of microservices...

1) RPC and remoting can leverage microservices, but are not required to. There is a very, very, low probability that people doing DCOM or SOAP were doing microservices. Modularity is an essential feature of microservices. Service experience does not necessarily translate to micro-service experience...

2) Is this GUI app service oriented? That is to say: despite its thick client, is it accessing network and shared resources in the networked environment? Because native GUI apps often talk with webservices. Maybe those are monolithic, maybe they're not, but the resource usage will have to do with development and maintenance of those service and its effect on the (fat) client.

3) Traditional three tier architectures struggle in numerous scenarios (particularly those where microservices thrive). Hexagonal architectures/DDD do well in those areas, provide all the same benefits and more, and are really not "cool" anymore. Also, those design styles can use microservices (or not), they're not dictated by them.

4) .Net Core 3 has a bunch of value adds for thick client WPF apps with no services -- side-by-side installations and such.

5) You should not ask your customers to waste money with microservices, nothing about .Net Core 3 would indicate that you should. Same deal for monolithic services... Just because MS launches something good for apples does not mean you should call your customers and tell them their oranges have to be thrown out.

> If you write code on .NET, you should adopt this release ASAP.

If you require the new features maybe, but if you are writing enterprise code, you shouldn't rush into things.

> Doubly so if you care about runtime performance.

Everyone cares about runtime performance, but if your software isn't experiencing performance issues, there is no need to rush into things. Or at the very least, reach out to your clients to get a feel about their schedules and expectations.

#1 rule: if it ain't broke, don't fix it.

I don't think he was suggesting anyone rush into anything. At the same time, a lot of "enterprise" software is still running on Java versions from over a decade ago, so perhaps they'd benefit if they had someone rushing them.
You are very correct, I'll try to temper my enthusiasm.
This is why I can't work in enterprise.
Smart man. Enterprise Dev/Arch here ;)
This is how legacy code is created isn't it?
What is wrong with legacy code? Isn't every code that is deployed to production legacy? Because you cannot just change it.
There are lots of ways you can end up with legacy code.

I've seen legacy code get created by people postponing platform updates for so long that the upgrade pathways stop being supported, that's one way.

I've also seen legacy code get created by people adopting the platform of the future super-early, and then being left high and dry when the rest of the world decided that platform wasn't actually the future after all, leaving them as the sole maintainers of the entire platform as well as their dependent code.

If your code currently works on standard .net, there's no reason to be in a massive hurry to move to .net core. There's not necessarily any reason to delay, either. It all depends on your business requirements and the investment required. If it's easy for you to move to .net core then by all means do it. If it's gonna be a massive project, let the smaller groups go first.

> I've seen legacy code get created by people postponing platform updates for so long that the upgrade pathways stop being supported, that's one way.

This is something i've seen many times, when you don't update in long enough entire API's might've changed or been replaced and there's no documentation or anyone even remembering the stuff available anymore.

I agree though that one doesn't have to rush new releases, i do however think there should be a plan to upgrade done as soon as there's a new stable release.

I've been working with a softphone that's built for .net framework 3.5, if you want any library you can forget nuget, must get source build and modify manually. Which is suboptimal.

Having a proper test suite and updating when the changes are minimal usually leads to better overall product maintenance.

I dont get these claims to not upgrade unless you're also just as worried about changing a line of code and having it all break too? Make the changes, test the changes, and deploy carefully, just as you would for anything else.

Unfortunately it's still a non-starter, because so many things I need that are also Microsoft SDKs are not ported, nor are they likely to ever be.

Also, we need a GUI, of some kind.

Which SDKs? Also there are several cross-platform GUI frameworks for .NET core already, it's really not worth that much to have yet another one.

Blazor (.NET webassembly) + Electron is an interesting option though for the future.

Various enterprisy things that tie in with Office in some way, shape, or fashion. The biggest one being the Skype for Business server SDK, which is some kind of bastard red-haired step-child, receiving only the most token updates since 2010, yet is massively important for doing anything productive that isn't supported out-of-the-box with their enterprise unified communications platform.
I believe much of that is now deprecated in favor of Office 365 APIs with the Microsoft Teams layer for communications.

Are you stuck on Skype for business due to enterprise policy?

Mostly due to customers that buy our software that are still running EOL versions of these products, or are in industries where running a SAAS version is never going to fly.

There is no Teams API to speak of, I'm super confused why Microsoft is pushing it so hard when they are wildly behind on the integrations that were promised already, and the functionality is behind the product that it is supposed to replace.

That's likely COM, meaning tough luck so far as netcore goes AFAIK. What you can do is wrap it in a service over something like HTTP or gRPC (even with a localhost NIC binding). Your codebase doesn't have to be homogeneous.
Thanks for the gist with the channels implementation.

I wish they worked on their release notes with samples for all the smaller features like formatters, pooling and channels. Too much of it is buried in github issues.

Any idea about required VS versions? The announcement makes no mention of Visual Studio (or maybe I missed it?) but the download pages says it requires a preview version of VS2017 which is unfortunate.
So the .NET Core SDK and command line tools do not require VS at all. VSCode works fine or whatever editor you like that supports omnisharp.

But if you are using VS you will need to update to 15.7 to take advantage of some of the features/

What is the best setup for coding .NET core on Mac? Rider? Asking because you seem to know what you’re talking about.
Rider presumably is better than VSCode if you do a lot of refactoring. If not, it's an overkill, and VSCode or slightly heavier Visual Studio for Mac are your best options.
I'm flattered, but unfortunately I'm not a mac person.

VSCode and Rider are the two standouts. I love VSCode on windows and Linux, but I have heard nothing but good things about Rider.

Rider is definitely the best IDE for .NET, regardless of platform.
I very much doubt it, given how InteliJ works on my laptop versus Visual Studio 2017.

Also where are Blend, the GUI tooling and rich debugging features from VS?

It is, I use both frequently and use Rider whenever I can and VS 2017 when working on projects Rider doesn't support. Although I don't use Designers so if you're building .NET GUI Apps VS 2017 would be better, but Rider is better for Web Apps, esp. Single Page Apps.

VS 2017 is the most unstable I can recall in recent memory, with constant crashes and White Screens of Death.

Completely disagree. It’s always a sign your OS has bad drivers, virus scanners or system libraries.
> VS 2017 is the most unstable I can recall in recent memory, with constant crashes and White Screens of Death.

Hmm, opposite of my experience. VS 2010 was the worst, and VS 2017 is actually pretty nice. Very frequent updates though, which is a little annoying.

2017 gets to be a little bit of a problem if you've got the Git tooling and ReSharper both going at the same time. On bigger solutions you're going to be hammering your disk swapping, so better hope you've got your code on an SSD, and that you've got exceptions in your antivirus to avoid real-time scanning those locations.
Thanks for the info all above posters. Sounds like dislikes for Rider are mostly from Windows users or people who need GUI support. I'm on Mac and have a lot of experience with Jetbrains IDE's so that's probably my best option.
I tried Rider may be 2-3 months ago and it was much much slower than Visual Studio 2017. I also had problems with font rendering (I use DPI > 100%) and all dialogs like open file are non-native, but from Java. Looks completely different than standard dialogs from Windows. So I will continue to use VS2017.
+1 for Rider or VSCode, twice Ive taken a laptop to a remote location and havent been able to login to VS and hence get no work done. The partner licensing for VS is apparently at fault.
I like VS Code for developing .NET Core Apps on OSX, it's a nice lightweight IDE with great multi terminal support. When your project gets larger Rider starts to become a good option, but if you're developing Web Apps, VS Code is better with greater support for SPA formats like Vue's SFC's, React's JSX, etc.
Thanks for the insight! Good answer.
Humble request: can anyone explain whether or not Span<T> is interesting if you mostly work with application code (as opposed to, say, low-level or framework code) and never work with unmanaged/native code, and why?

From my perspective, it seems like something that'll be used in the guts of ASP.NET and the rest of the base class library that will benefit the performance of my code, but I'd never really use it directly.

Correct. Most developers will not deal with it much directly, particularly not in the way that it is used in the "guts" of the product.
It can help prevent allocations if you work with large arrays or strings
If you take substrings of strings; using string.AsSpan() then allows you to work it as a Span<T> and take windows of the string without allocating an new string for the substrings.

Also it means you can now pass readonly arrays (the elements) to things using ReadOnlySpan<T>; so don't have to do defensive copies

If you are at the application level then you can use whatever, but Span<T> is pretty handy. If you are calling an method that has both Span and Array overloads, prefer the Span version since it is less likely to copy or allocate.

The real selling point is that Span is much more flexible than an Array. Both Managed and Unmanged memory can work with it. If you load a big string and need to get each line from it, you can slice into the middle of the string safely and get a ReadOnlySpan<char> that supports most 'string' operations without allocating any memory.

Or imagine you need to process some huge file, typically you would read it chunk by chunk copying the data from the Stream into some byte[]. But with Span you could open a Memory Mapped File and work on segments of the file without copying into temp buffers.

You gain a lot by avoiding memory copies and by allocating fewer objects (less work for the GC). For some workloads then can be a huge speedup.

Span (safely refers to data anywhere) and Memory (safely refers to data on the heap only) have a much nicer API than arrays. ArraySegment has had a facelift but to nit: ArraySegment is a pain to type. Also, unlike arrays, there are read-only variants - which are good for rich type checking. In addition you can easily reinterpret cast between blittable types (the new 'unmanaged' generic constraint) for when you are participating in mortal sins such as directly serializing byte representations.

Tons of reasons to use them besides performance. We use them for those reasons and if there is a performance boon, great bonus!

This appears to imply that for brand new code with no dependencies, arrays are essentially obsoleted by Span/Memory. Is that a fair statement?
Anybody knows how much improvement can you expect from tiered compilation? And are there any drawbacks - is it stable?
Right now I wouldn't expect much. I did some very very rudimentary benchmarks and saw a slight drop in perf using Tiered Compilation.

But now that it exists we can expect regular improvements with every point release.

It depends on your app. We've seen massive improvements for webservers and long-running apps. Short-lived apps don't benefit. We'll be posting more on it soon. Give it a try!
This guy works on dotnet his answer is much better than mine.
My app is a asp web app that spends most of its cycles in ef core code and unmanaged.

Would be nice to read more about it especially how to measure performance benefits

Does it ever optimize more aggressively than previously? i.e. would we see, as a bad but relatable example, more functions inlined?
One benefit caught my eye, but was not explained:

"Much easier to manage platform dependencies in project files and with self-contained application publishing."

Anybody know anything about this? I frequently deal with applications that have platform specific components, and it's a real pain. Sometimes the platform specific code is a platform-specific native dll that gets called from the same P/Invoke wrapper, sometimes it's two different managed implementations of the same interface, sometimes it's both. It'd be great if this sort of thing got easier to do.

Sorry! Poor wording on my part.

I updated the wording to: "Much easier to manage .NET Core and ASP.NET Core versions in project files and with self-contained application publishing."

The thing that you are talking about still needs to be improved. Sadly, that didn't happen in this release.

This does not mention my favorite new feature: BindingFlags.DoNotWrapExceptions. It lets you prevent exceptions from being wrapped in TargetInvocationException when invoking methods using reflection. I wrote about this feature here if anyone is interested: http://www.awise.us/2018/04/25/do-no-wrap-exceptions.html
wow, this is huge for some use cases!
Is there any data on the size of the .NET Core user base? It was my impression that .NET Core was unsuitable for production deployments so far. Also, .NET Core is primarily targeted at Linux users, right? Why would you even consider using .NET Core on Windows when you can utilize a fully featured .NET Framework?
Few points:

- Deployments: https://www.microsoft.com/net/customers

- Monthly engaged developers is >500k for NET Core.

- >50% of developers are on Windows.

Note that some of the pull quotes on that site don't specify .NET Core, and probably predate it (e.g. the Stack Overflow story dates back to 2014, and refers to Framework).

We know that .NET Core is generally liked by Microsoft developers (with good reason), but I have no idea what corporate adoption is like, and would love to see indicators that people are actually migrating production systems. The existance of Core makes Framework that bit more annoying to deal with, and it would be nice to see that things are moving.

Stackoverflow team contributes to .NET Core itself since pre 1.0 dates. It is a pretty safe bet that they use it in production.

Corporate adoption is very good afaik. For .NET developers, .NET Core is a lot of fresh air and also a long overdue defence against Node. They want to continue to work with C# :)

> For .NET developers, .NET Core is a lot of fresh air and also a long overdue defence against Node.

Really?! US .NET developers or what?

I never worried about Node ever, with so many nice languages in .NET and Java worlds to chose from.

UWP uses .NET Core alongside .NET Native toolchain.

Now with .NET Core 3.0 roadmap and MSIX containers, their are slowly merging Win32 and UWP worlds.

It's growing rapidly and .NET Core is definitely ready for production, has been for the last 2 years.

It's not a simple subset of .NET Framework, there are distinct differences and cross-platform is just one ability. It's also smaller, faster, and allows for self-contained deployments that can run with other apps using different framework versions on the same machine. Also very simple to use in containers.

https://docs.microsoft.com/en-us/dotnet/standard/choosing-co...

> Is there any data on the size of the .NET Core user base? It was my impression that .NET Core was unsuitable for production deployments so far.

.NET core is a fully supported option on Google's AppEngine via flexible instances, so I think it's stable enough for production deployments.

I'm most excited about the added SourceLink support. This will allow us to see and navigate library sources right in the IDE and also allow us to step through library code when debugging.
What is the difference between Core and Framework?
Biggest difference is core is cross platform.
Core is a portable re-implementation of the Framework

https://docs.microsoft.com/en-us/dotnet/standard/choosing-co...

So basically a renamed Mono?
No. I believe it's a fork of the Silverlight runtime, used to be a tiny 2MB runtime to compete with Flash on the browser.
Microsoft open sourced Dotnet to have others port it to different platforms and fork the code not rename it. Big difference between just renaming something and forking it under a different name.

The license allows it to be forked.

It is the runtime from the Silverlight Project, which evolved over the years for their Windows Phone and later UWP platforms. .NET Core is a very old platform already. It shares the jitter and the garbage collector with the full framework.

It is actually the opposite of your statement. Mono is massively adopting .NET Core source code but without loosing their own benefits (portability and factoring).

Does anyone else experience high CPU on mac when running dotnet run?
Just a reminder, telemetry is opt-out: https://news.ycombinator.com/item?id=17177241

Be sure to check your environment variables are set properly. Also, be sure to check that they haven't added additional opt-out settings, or remove the ability to opt-out all together. If you haven't opted-out on purpose, be sure you're still OK with what they're collecting.

And I just realise, .Net Core is MIT licensed..... that is far too good to be true right?

Given the immense engineering hours went into CoreCLR, why aren't more languages built on top of .NET runtime?

There are scattered few. Leppie has maintained IronScheme for years now and the good folks as Peachpie have PHP running on CoreClr(via Roslyn even!)
Why more if you have good oo, procedurel and functional contenders :). C# and F# are top contenders in their areas.

Language alternatives show up by need (not given here) or specialization (niche you never heard of).