.NET Framework – walk-through – Part 12

.NET Core

The following is a partial list of the commands.

The telemetry feature is on by default. The data collected is anonymous in nature and will be published in an aggregated form for use by both Microsoft and community engineers under a Creative Commons license.

You can opt-out of the telemetry feature by setting an environment variable DOTNET_CLI_TELEMETRY_OPTOUT (e.g. export on OS X/Linux, set on Windows) to true (e.g. “true”, 1). Doing this will stop the collection process from running.

Testrunner

Fact

.NET Core is a platform made of NuGet packages.

The ‘lib’ and ‘ref‘ terms refer to folders in NuGet packages. ‘ref’ folders describe the public API of a package via assembly metadata. ‘lib’ folders
contain the implementation of that public API for a given framework.

Note that a portable app with third-party dependencies will only be as portable as its third-party dependencies. For example, if a third-party
library only supports macOS, the app will not be portable to Windows systems.

Sample project.json file

Note that you can only deploy a self-contained app with a third-party library to platforms supported by that library.

The version number of the .NET Framework doesn’t necessarily correspond to the version number of the CLR it includes.
It’s good programming practice to catch a specific type of exception rather than use a basic catch statement.

It is good coding practice to add information to an exception that is re-thrown to provide more information when debugging.

Throw exceptions instead of returning an error code.

Exceptions ensure that failures do not go unnoticed because calling code didn’t check a return code.

.NET includes a set of delegate types that programmers can reuse and not have to create new types. These are Func<>, Action<> and Predicate<>, and
they can be used in various places throughout the .NET APIs without the need to define new delegate types.

● Action<> is used when there is a need to perform an action using the arguments of the delegate.
● Func<> is used usually when you have a transformation on hand, that is, you need to transform the arguments of the delegate into a different
result. Projections are a prime example of this.
● Predicate<> is used when you need to determine if the argument satisfies the condition of the delegate. It can also be written as a Func<T,
bool>.

It’s important to reason about tasks as abstractions of work happening asynchronously, and not an abstraction over threading. Tasks can be
explicitly requested to run on a separate thread via the Task.Run API.

async and await are the best practice managing CPU-bound work when you need responsiveness.

PerfView traces show that the performance of the new C# and Visual Basic compilers is rarely CPU bound.

Keep in mind the four facts for tuning your apps:
Don’t prematurely optimize – be productive and tune your app when you spot problems.
Profiles don’t lie – you’re guessing if you’re not measuring.
Good tools make all the difference – download PerfView and try it out.
It’s all about allocations – that is where the compiler platform team spent most of their time improving the performance of the new compilers.

After the Lazy object is created, no instance of Orders is created until the Value property of the Lazy variable is accessed for the first time. On first access, the wrapped type is created and returned, and stored for any future access.

For example, to analyze foo.dll against .NET Core and the latest .NET Framework and get an HTML report, the following command would be run:
ApiPort.exe analyze -f foo.dll -t “.NET CORE, Version=5.0” -t “.NET Framework” -r HTML

Line #5 introduces the DllImport attribute. This attribute is crucial, as it tells the runtime that it should load the unmanaged DLL. This is the DLL into which we wish to invoke.

Line #6 is the crux of the P/Invoke work. It defines a managed method that has the exact same signature as the unmanaged one. The declaration has a new keyword that you can notice, extern, which tells the runtime this is an external method, and that when you invoke it, the runtime should find it in the DLL specified in DllImport attribute.

If you are only reading from a shared collection, then you can use the classes in the System.Collections.Generic namespace. We recommend that you do not use System.Collections collection classes unless you are required to target the .NET Framework 1.1 or earlier runtime.

The ConcurrentQueue<T> and ConcurrentStack<T> classes do not use locks at all. Instead, they rely on Interlocked operations to achieve thread-safety.

Interlocked Notes:

1. INTERLOCKED METHODS ARE CONCURRENTLY SAFE ON ANY NUMBER OF COREs OR CPUs.
2. Interlocked methods apply a full fence around instructions they execute, so reordering does not happen.
3. Interlocked methods do not need or even do not support access to a volatile field, as volatile is places a half fence around operations on given
field and interlocked is using the full fence.

Interlocked functions do not lock. They are atomic, meaning that they can complete without the possibility of a context switch during increment. So
there is no chance of deadlock or wait.

This is safe to do (provided you remember to lock everywhere else that you access this.counter). It prevents any other threads from executing any other code which is guarded by locker. Using locks also, prevents the multi-CPU reordering problems as above, which is great.

The problem is, locking is slow, and if you re-use the locker in some other place which is not really related then you can end up blocking your other threads for no reason.

Any time two threads operate on a shared variable concurrently, and one of those operations performs a write, both threads must use atomic operations.

Atomic operations are ones which manipulate memory in a way that appears indivisible (incapable of being divided by a specific integer without leaving a remainder): No thread can observe the operation half-complete. On modern processors, lots of operations are already atomic.
For example, aligned reads and writes of simple types are usually atomic.

Lock method will call a Monitor.Enter(Object) and Monitor.Exit() in System.Threading.Monitor Class to mark if the current object has been locked or unlocked. So Lock’s performance should be slower than Interlocked.

SpinLock A very low-level, CPU-intensive lock. Good for situations where the lock is held a very short amount of time.

Leave a Reply

Your email address will not be published. Required fields are marked *