Scott Hanselman

Dotnet could not execute because the application was not found or a compatible .NET SDK is not installed

October 07, 2021 Comment on this post [0] Posted in DotNetCore
Sponsored By

I ran into this interesting issue where my System PATH environment variables got out of order. I ran "dotnet --version" and saw an error I'd not seen before. Dotnet "Could not execute because the application was not found or a compatible .NET SDK is not installed." What's that?

How did I diagnose this?

dotnet can't run because the application was not found

From the command prompt, I typed "where dotnet" to ask cmd.exe "which dotnet.exe are you offering me and in what order?" You would use the which command in Linux, the where command in DOS, and the more explicit where.exe dotnet on PowerShell.

Here I can see that Program Files (x86) has a dotnet.exe that is FIRST in the Path before the x64 version I expected.

Digging into GitHub I can see that the bug has been fixed but it's good to know how things get into a weird state and how easy it is to fix. In this case, I just swapped (or removed) the x86 and x64 (native architecture) paths in my System PATH via the environment variables UI in Windows. Just type Start and Environment Variables, click it, and then Double Click (or Edit) the PATH variable for a nice UI experience. You can even "move up and move down" within that UI - far nicer than editing a text file.

This can happen when you install a 32-bit .NET SDK on a 64-bit system and the last one in wins. In my case, I don't need a 32-bit host at all in my PATH so I ended up just removing it from my PATH completely.

Hope this helps you if you hit it and glad it's fixed.


Sponsor: YugabyteDB is a distributed SQL database designed for resilience and scale. It is 100% open source, PostgreSQL-compatible, enterprise-grade, and runs across all clouds. Sign up and get a free t-shirt!

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Hosting By
Hosted in an Azure App Service

Shrink your WSL2 Virtual Disks and Docker Images and Reclaim Disk Space

October 05, 2021 Comment on this post [8] Posted in Docker | Linux
Sponsored By

Docker Desktop for Windows uses WSL to manage all your images and container files and keeps them in a private virtual hard drive (VHDX) called ext4.vhdx.

It's usually in C:\Users\YOURNAME\AppData\Local\Docker\wsl\data and you can often reclaim some of the space if you've cleaned up (pruned your images, etc) with Optimize-Vhd under an administrator PowerShell shell/prompt.

You'll need to stop Docker Desktop by right clicking on its tray icon and choosing Quit Docker Desktop. Once it's stopped, you'll want to stop all running WSL2 instances with wsl --shutdown

Mine was 47gigs as I use Docker A LOT so when I optimize it from admin PowerShell from the wsl\data folder

optimize-vhd -Path .\ext4.vhdx -Mode full

...it is now 2 gigs smaller. That's nice, but it's not a massive improvement. I can run docker images and see that many are out of date or old. If I'm not using Kubernetes I can turn it off and delete those containers as well from the Docker settings UI.

I'll run docker system prune -a to AGRESSIVELY tidy up. Read about these commands before your try yourself. -a means all unused images, not just dangling ones. Don't delete anything you love or care about. If you're worried, docker system is safer without the -a.

Now my Docker WSL 2 VHD is 15 gigs smaller! Learn more about WSL, Windows 11, and WSLg on my latest YouTube!

NOTE: You can now get WSL from the Windows Store! Go get it here and then run "wsl --install" at your command line.

If you want, you can also go find your Ubuntu and other WSL disks and Compact them as well. I only think about this once or twice a year, so don't consider this a major cleanup thing unless you're really tight on space.

Ubuntu WSL disks will be in folders with names like

C:\Users\scott\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu18.04onWindows_79rhkp1fndgsc\LocalState

or

C:\Users\scott\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu20.04onWindows_79rhkp1fndgsc\LocalState

But you will want to look around for yours. Again, back things up and make sure WSL is shutdown first!

Enjoy! REMEMBER - Be sure to back things up before you run commands as admin from some random person's blog. Have a plan.


Sponsor: YugabyteDB is a distributed SQL database designed for resilience and scale. It is 100% open source, PostgreSQL-compatible, enterprise-grade, and runs across all clouds. Sign up and get a free t-shirt!

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Hosting By
Hosted in an Azure App Service

ASP.NET Core Diagnostic Scenarios

September 30, 2021 Comment on this post [2] Posted in ASP.NET | DotNetCore | Open Source
Sponsored By

ThreadingDavid and friends has a great repository filled with examples of "broken patterns" in ASP.NET Core applications. It's a fantastic learning resource with both markdown and code that covers a number of common areas when writing scalable services in ASP.NET Core. Some of the guidance is general purpose but is explained through the lens of writing web services.

Here's a few great DON'T and DO examples, but be sure to Star the repo and check it out for yourself! This is somewhat advanced stuff but if you are doing high output low latency web services AT SCALE these tips will make a huge difference when you're doing a something a hundred thousand time a second!

DON'T - This example uses the legacy WebClient to make a synchronous HTTP request.

public string DoSomethingAsync()
{
var client = new WebClient();
return client.DownloadString(http://www.google.com);
}

DO - This example uses an HttpClient to asynchronously make an HTTP request.

static readonly HttpClient client = new HttpClient();

public Task<string> DoSomethingAsync()
{
return client.GetStringAsync("http://www.google.com");
}

Here's a list of ASP.NET Core Guidance. This one is fascinating. ASP.NET Core doesn't buffer responses which allows it to be VERY scalable. Massively so. As such you do need to be aware that things need to happen in a certain order - Headers come before Body, etc so you want to avoid adding headers after the HttpResponse has started.

DON'T - Add headers once you've started sending the body.

app.Use(async (next, context) =>
{
await context.Response.WriteAsync("Hello ");

await next();

// This may fail if next() already wrote to the response
context.Response.Headers["test"] = "value";
});

DO - Either check if it's started before you send the headers:

app.Use(async (next, context) =>
{
await context.Response.WriteAsync("Hello ");

await next();

// Check if the response has already started before adding header and writing
if (!context.Response.HasStarted)
{
context.Response.Headers["test"] = "value";
}
});

Or even BETTER, add the headers on the OnStarting call back to guarantee they are getting set.

app.Use(async (next, context) =>
{
// Wire up the callback that will fire just before the response headers are sent to the client.
context.Response.OnStarting(() =>
{
context.Response.Headers["test"] = "value";
return Task.CompletedTask;
});

await next();
});

There's a ton of great guidance around async programming. If you are returning something small or trivial, like a simple value, DON'T Task<>:

public class MyLibrary
{
public Task<int> AddAsync(int a, int b)
{
return Task.Run(() => a + b);
}
}

DO use ValueTask<> as this example not only doesn't use an extra threads and avoids heap allocation entirely:

public class MyLibrary
{
public ValueTask<int> AddAsync(int a, int b)
{
return new ValueTask<int>(a + b);
}
}

There's a ton of good learning over there so go check it out! https://github.com/davidfowl/AspNetCoreDiagnosticScenarios


Sponsor: Make login Auth0’s problem. Not yours. Provide the convenient login features your customers want, like social login, multi-factor authentication, single sign-on, passwordless, and more. Get started for free.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Hosting By
Hosted in an Azure App Service

Differences between Hashtable vs Dictonary vs ConcurrentDictionary vs ImmutableDictionary

September 28, 2021 Comment on this post [9] Posted in DotNetCore | Musings
Sponsored By

DictionariesI'm very much enjoying David Fowler's tweets, and since he doesn't have a blog, I will continue to share and expand on his wisdom so that it might reach a larger audience.

He had a conversation with Stephen Toub where Stephen points out that ".NET has 4 built-in dictionary/map types [and] there’s no guidance on when to use what, mostly individual documentation on each implementation."

  • Hashtable
  • Dictionary
  • ConcurrentDictionary
  • ImmutableDictionary

There is actually some good documentation on C# Collections and Data Structures here that we can compare and combine with Stephen Toub's good advice (via David) as well!

There are two main types of collections; generic collections and non-generic collections. Generic collections are type-safe at compile time. Because of this, generic collections typically offer better performance.

Definitely important to remember. Generics have been around since .NET Framework 2.0 around 15 years ago so this is a good reason to consider avoiding Hashtable and using Dictionary<> instead. Hashtable is weakly typed and while it allows you to have keys that map to different kinds of objects which may seem attractive at first, you'll need to "box" the objects up and boxing and unboxing is expensive. You'll almost always want to use Dictionary instead.

If you're accessing your collection across threads, consider the System.Collections.Concurrent namespace or using System.Collections.Immutable which is thread-safe because you'll always be working on a copy as the original collection is immutable (not modifiable).

David says this about

  • ConcurrentDictionary - "Good read speed even in the face of concurrency, but it’s a heavyweight object to create and slower to update."

Or perhaps

  • Dictionary with lock - "Poor read speed, lightweight to create and medium update speed."
  • Dictionary as immutable object - "best read speed and lightweight to create but heavy update. Copy and modify on mutation e.g. new Dictionary(old).Add(key, value)"
  • Hashtable - "Good read speed (no lock required), same-ish weight as dictionary but more expensive to mutate and no generics!"
  • ImmutableDictionary - "Poorish read speed, no locking required but more allocations require to update than a dictionary."

Another one that isn't often used but I'll add as it's good to know about is

  • KeyedCollection - Generic and ordered. Uses Dictionary and List underneath

This is great advice from David:

Use the most obvious one until it bites you. Most software engineering is like this.

Measure and test, measure and test. Good luck to you!


Sponsor: Make login Auth0’s problem. Not yours. Provide the convenient login features your customers want, like social login, multi-factor authentication, single sign-on, passwordless, and more. Get started for free.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Hosting By
Hosted in an Azure App Service

How to make Shared Google Calendars show up on your iPhone and iPad Calendar

September 23, 2021 Comment on this post [0] Posted in Musings
Sponsored By

My niece just started her MBA at a local university and that uni is a G Suite/Google/Gmail user. Her professors share their class calendars (vs inviting the students to events) so everything is a "Shared with You" shared calendar. That means the events aren't on your primary Google Calendar, they are read-only shares to you.

My niece uses an iPhone and wanted to calendars to sync with her iPhone calendar she already uses. Google help and everyone else says "install Google Calendar." Sure, that works and she can see the calendars in that other apps, but again, it's totally not integrated with her life and existing Calendar App on iPhone, Mac, and iPad.

Turns out there is a 12 year old page deep in Google Calendar at https://www.google.com/calendar/syncselect that you can visit to "reshare" those shared calendars to external users like iOS. Love that Copyright 2009 action and the ongoing dedication to improvement in Google Suite and Calendar for the real features that people need /s.

Google Calendar Sync Select

Make sure you are signed into the right Google Account before you click that link. At this point, return to your iPhone/iPad Calendar app and tap Calendars at the bottom. Check the ones you want to see, and press done. Wait a few minutes and your Google Shared Calendars will start to sync to your iOS Calendar!

Hope this helps.


Sponsor: YugabyteDB is a distributed SQL database designed for resilience and scale. It is 100% open source, PostgreSQL-compatible, enterprise-grade, and runs across all clouds. Sign up and get a free t-shirt.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Hosting By
Hosted in an Azure App Service

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.