Warning about server GC in F# project - .net-core

I am working on my very first F# project and I am experimenting with the Hopac library.
I am on dotnet version 3.1.300 on a Mac. I have initialized my project using the following:
dotnet new console --language F#
dotnet add package Hopac
And after writing using the Hopac library ran the program in the following way:
dotnet run
The runtime behaviour of the program works according to my expectations but I get the following warning:
WARNING: You are using single-threaded workstation garbage collection, which means that parallel programs cannot scale. Please configure your program to use server garbage collection.
As recommended in a few threads in SO to add the following clause:
<ServerGarbageCollection>true</ServerGarbageCollection>
I have tried the following in my fsproj configuration:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<ServerGarbageCollection>true</ServerGarbageCollection>
</PropertyGroup>
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Include="Program.fs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Hopac" Version="0.4.1" />
</ItemGroup>
</Project>
Additionally I have also tried:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<ServerGarbageCollection>true</ServerGarbageCollection>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Include="Program.fs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Hopac" Version="0.4.1" />
</ItemGroup>
</Project>
but the same warning persists. I am an absolute novice on .NET configuration files so am I making some obvious errors? Thanks

Create a runtimeconfig.template.json at the root of your project
{
"configProperties": {
"System.GC.Server": true
}
}
To verify is working, inside your code print:
printfn "%A" System.Runtime.GCSettings.IsServerGC
It should be true.
For some reason the SDK version of the setting does not work.

Related

Can a .NET 5 project be set up to always build with release configuration?

I have a small .NET 5 project whose project file is shown below.
This project will be used to run performance benchmarks against my main project. As such, I'd like to always build it with the release configuration.
The documentation for the -c option of dotnet build command does say the following, but I haven't found any reference to it in the project file section:
The default for most projects is Debug, but you can override the build
configuration settings in your project.
Is there a way to specify this in the project file rather than having to write dotnet build -c release each time I run it?
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Include="Program.fs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Domain\Domain.fsproj" />
</ItemGroup>
</Project>
Yes, you can add <Configuration>Release</Configuration> to the property group. See the corresponding MSBuild documentation.

Using dependency of dependency in .NET Core

I'm trying to understand how dependencies work in .NET Core.
Let's say I have 2 projects. The Project1 has this definition:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Project2\Project2.csproj" />
</ItemGroup>
</Project>
And this single class which uses the Newtonsoft.Json dependency:
public class Wizard
{
public void DoMagic()
{
var settings = Newtonsoft.Json.JsonConvert.DefaultSettings;
}
}
As you can see, it also references Project2, which has the following definition:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
</ItemGroup>
</Project>
When I remove the Newtonsoft.Json package reference from the Project1, I would expect it to no longer compile... But it does compile! As it seems, it's able to use the Newtonsoft.Json that is a dependency of Project2.
So I have 2 questions:
I've done my tests with an "internal" project reference for convenience, but does this work the same way with external package references (i.e. NuGet)?
Can anybody explain the rationale here? It seems risky to me, a change of a dependency in any of the dependencies of my project can break my project, if it is using that sub-dependency. In other words, why is this allowed? It seems to be always a bad idea to use implicitly a dependency of a dependency, because it could change and break your code, so why does the framework allow this?
Yes, that's how it works across everything.
You can use PrivateAssets to control this:
https://learn.microsoft.com/en-us/nuget/consume-packages/package-references-in-project-files#controlling-dependency-assets

JUnitTestLogger.dll is not copied on build when it is a transitive dependency

I'm making a core package for all the test projects in several solutions. A dependency graph is like:
MyTests.csproj -> MyTestFramework (nuget package) -> JUnitTestLogger (nuget package)
The problem is JUnitTestLogger.dll has to be copied to the output folder on the build of MyTests.csproj, or it just doesn't work. OK, I add:
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
to MyTests.csproj and build again. As a result, there is every transitive dependency dll in the output folder... except for JUnitTestLogger.dll. I've checked its source code JUnitTestLogger.csproj and found nothing special.
What's wrong with this package, why is it not copied? I'm asking here, not on Github because of low activity at the project's repo.
MyTests.csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MyTestFramework" Version="1.2.3" />
</ItemGroup>
</Project>
MyTestFramework.csproj (part):
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<IsPackable>true</IsPackable>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="JUnitTestLogger" Version="1.1.0" />
</ItemGroup>
</Project>
Auto-generated MyTestFramework.nuspec (part):
<dependencies>
<group targetFramework=".NETCoreApp2.2">
<dependency id="JUnitTestLogger" version="1.1.0" exclude="Build,Analyzers" />
</group>
</dependencies>
I'm a maintainer on JunitXml.TestLogger (A newer package than the one you mentioned, but both were forked from the same source in Github/Spekt and share some code). The main thing I am aware of that is unusual with the test loggers is that they are referenced in your project, but not used by the code.
I haven't seen this specific issue, but there have been several in the past like this one where the library isn't copied on build. When I first used these libraries I had to put extra steps in my CI builds to copy the library in. From what I recall, my solution was the same as the one in the issue, which was to switch from msbuild to dotnet build. So maybe that or one of the other closed issues there will give a clue.

Process creation failed with error: Access is denied when starting project in debug mode

I have an ASP.NET Core project targeting net4.6.1
The following error is thrown every time I try to start the project with debugging, from both VS2017 and command line using dotnet run.
The csproj is the following:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net461</TargetFramework>
<Platforms>x64</Platforms>
<AspNetCoreHostingModel>OutOfProcess</AspNetCoreHostingModel>
<AspNetCoreModuleName>AspNetCoreModule</AspNetCoreModuleName>
<StartupObject></StartupObject>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.HttpsPolicy" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\pathToAnotherProject\myproject.csproj" />
</ItemGroup>
</Project>
I can mention that I have a single startup project created as an ASP.NET Core project and multiple .net core class library projects targeting net461.
Any idea where the problem comes from?
Have you tried to enable 'use managed compatibility mode' in the debugging>general section of VS2017 options.

Patch version of ASP Core (preview 4) with AppVeyor

How to patch Asp.Net Core project (csproj) in order to build versioned binaries with AppVeyor?
Is there a way to apply versioning separately for AssemblyVersion and FileVersion?
AppVeyor has predefined step to patch AssemblyInfo.cs file, but it isn't included into project and functionality of AssemblyInfo moved to csproj file, therefore it's not clear how to deal with versioning.
Appreciate you help!
As .NET Core .csproj is a regular XML you can use PowerShell script to update the version information in it. For example, you might have the following MyProject\MyProject.csproj:
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp1.0</TargetFramework>
<Version>1.2.3.4</Version>
</PropertyGroup>
<ItemGroup>
<Compile Include="**\*.cs" />
<EmbeddedResource Include="**\*.resx" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NETCore.App" Version="1.0.1" />
</ItemGroup>
</Project>
Then on AppVeyor the script patching <Version> would be the following:
$xmlPath = "$env:appveyor_build_folder\MyProject\MyProject.csproj"
$xml = [xml](get-content $xmlPath)
$propertyGroup = $xml.Project.PropertyGroup | Where { $_.Version}
$propertyGroup.Version = $env:appveyor_build_version
$xml.Save($xmlPath)

Resources