Categories
C# dispose

Easy Pattern to implement IDisposable

Here is my C# implementation for an easy way to implement the IDisposable pattern in your classes.

Just override DisposeManaged() and/or DisposeNative() when needed.

The embedded code shown below is pulled directly from my GitHub gist here.
If any formatting is ‘off’ or links don’t work, contact the WordPress.com complaint department. :/

// Copyright © Protiguous. All Rights Reserved.
//
// This entire copyright notice and license must be retained and must be kept visible in any binaries, libraries, repositories, or source code (directly or derived) from our binaries, libraries, projects, solutions, or applications.
//
// All source code belongs to Protiguous@Protiguous.com unless otherwise specified or the original license has been overwritten by formatting. (We try to avoid it from happening, but it does accidentally happen.)
//
// Any unmodified portions of source code gleaned from other sources still retain their original license and our thanks goes to those Authors.
// If you find your code unattributed in this source code, please let us know so we can properly attribute you and include the proper license and/or copyright(s).
//
// If you want to use any of our code in a commercial project, you must contact Protiguous@Protiguous.com for permission, license, and a quote.
//
// Donations, payments, and royalties are accepted via bitcoin:1Mad8TxTqxKnMiHuZxArFvX8BuFEB9nqX2 and PayPal:Protiguous@Protiguous.com
//
// ====================================================================
// Disclaimer: Usage of the source code or binaries is AS-IS.
// No warranties are expressed, implied, or given.
// We are NOT responsible for Anything You Do With Our Code.
// We are NOT responsible for Anything You Do With Our Executables.
// We are NOT responsible for Anything You Do With Your Computer.
// ====================================================================
//
// Contact us by email if you have any questions, helpful criticism, or if you would like to use our code in your project(s).
// For business inquiries, please contact me at Protiguous@Protiguous.com.
//
// Our software can be found at "https://Protiguous.Software/"
// Our GitHub address is "https://github.com/Protiguous".
//
// File "ABetterClassDispose.cs" last formatted on 2020-11-07.
#nullable enable
namespace Librainian.Utilities {
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Threading;
/// <summary>
/// <para>A class for easier implementation the proper <see cref="IDisposable" /> pattern.</para>
/// <para>Implement overrides on <see cref="DisposeManaged" />, and <see cref="DisposeNative" /> as needed.</para>
/// <code></code>
/// </summary>
/// <remarks>ABCD (hehe).</remarks>
/// <copyright>Created by Protiguous.</copyright>
public abstract class ABetterClassDispose : IDisposable {
private Int32 _hasDisposedManaged;
private Int32 _hasDisposedNative;
private Int32 _hasSuppressedFinalize;
public Boolean HasDisposedManaged {
[MethodImpl( MethodImplOptions.AggressiveInlining )]
[DebuggerStepThrough]
get => Interlocked.CompareExchange( ref this._hasDisposedManaged, 0, 0 ) == 1;
[MethodImpl( MethodImplOptions.AggressiveInlining )]
[DebuggerStepThrough]
set {
if ( this.HasDisposedManaged ) {
return; //don't allow the setting to be changed once it has been set.
}
Interlocked.Exchange( ref this._hasDisposedManaged, value ? 1 : 0 );
}
}
public Boolean HasDisposedNative {
[MethodImpl( MethodImplOptions.AggressiveInlining )]
[DebuggerStepThrough]
get => Interlocked.CompareExchange( ref this._hasDisposedNative, 0, 0 ) == 1;
[MethodImpl( MethodImplOptions.AggressiveInlining )]
[DebuggerStepThrough]
set {
if ( this.HasDisposedNative ) {
return; //don't allow the setting to be changed once it has been set.
}
Interlocked.Exchange( ref this._hasDisposedNative, value ? 1 : 0 );
}
}
public Boolean HasSuppressedFinalize {
[MethodImpl( MethodImplOptions.AggressiveInlining )]
[DebuggerStepThrough]
get => Interlocked.CompareExchange( ref this._hasSuppressedFinalize, 0, 0 ) == 1;
[MethodImpl( MethodImplOptions.AggressiveInlining )]
[DebuggerStepThrough]
set {
if ( this.HasSuppressedFinalize ) {
return; //don't allow the setting to be changed once it has been set.
}
Interlocked.Exchange( ref this._hasSuppressedFinalize, value ? 1 : 0 );
}
}
/// <summary>Can be changed to a property, if desired.</summary>
/// <returns></returns>
public Boolean IsDisposed => this.HasDisposedManaged && this.HasDisposedNative;
/// <summary>
/// <para>
/// Disposes of managed resources, then unmanaged resources, and then calls <see cref="GC.SuppressFinalize" /> for this object.
/// </para>
/// <para>Note: Calling <see cref="Dispose()" /> multiple times has no effect beyond the first call.</para>
/// </summary>
[DebuggerStepThrough]
public void Dispose() {
if ( !this.HasDisposedManaged ) {
try {
this.DisposeManaged(); //Any derived class should have overloaded this method and disposed of any managed objects inside.
}
catch ( Exception exception ) {
Debug.WriteLine( exception );
}
finally {
this.HasDisposedManaged = true;
}
}
if ( !this.HasDisposedNative ) {
try {
this.DisposeNative(); //Any derived class should overload this method.
}
catch ( Exception exception ) {
Debug.WriteLine( exception );
}
finally {
this.HasDisposedNative = true;
}
}
if ( this.IsDisposed && !this.HasSuppressedFinalize ) {
try {
GC.SuppressFinalize( this );
}
catch ( Exception exception ) {
Debug.WriteLine( exception );
}
finally {
this.HasSuppressedFinalize = true;
}
}
}
/// <summary>
/// Just calls <see cref="Dispose()" />. The parameter <paramref name="dispose" /> has no effect with this design.
/// </summary>
/// <param name="dispose"></param>
[DebuggerStepThrough]
public void Dispose( Boolean dispose ) => this.Dispose();
/// <summary>Override this method to dispose of any <see cref="IDisposable" /> managed fields or properties.</summary>
/// <example>
/// <code>using var bob = new DisposableType();</code>
/// </example>
[DebuggerStepThrough]
public virtual void DisposeManaged() { }
/// <summary>
/// Dispose of COM objects, handles, etc in this method.
/// </summary>
[DebuggerStepThrough]
public virtual void DisposeNative() =>
/*make this virtual so it is optional*/
this.HasDisposedNative = true;
/*
/// <summary>Set via <see cref="SetDisposeHint" /> to help find if an object has not been disposed of properly.</summary>
[CanBeNull]
private String? DisposeHint { get; set; }
*/
/*
/// <summary>Call at any time to set a debugging hint as to the creator of this disposable.</summary>
/// <param name="hint"></param>
[Conditional( "DEBUG" )]
public void SetDisposeHint( [CanBeNull] String? hint ) => this.DisposeHint = hint;
*/
}
}
// Copyright © Protiguous. All Rights Reserved.
//
// This entire copyright notice and license must be retained and must be kept visible in any binaries, libraries, repositories, or source code (directly or derived) from our binaries, libraries, projects, solutions, or applications.
//
// All source code belongs to Protiguous@Protiguous.com unless otherwise specified or the original license has been overwritten by formatting. (We try to avoid it from happening, but it does accidentally happen.)
//
// Any unmodified portions of source code gleaned from other sources still retain their original license and our thanks goes to those Authors.
// If you find your code unattributed in this source code, please let us know so we can properly attribute you and include the proper license and/or copyright(s).
//
// If you want to use any of our code in a commercial project, you must contact Protiguous@Protiguous.com for permission, license, and a quote.
//
// Donations, payments, and royalties are accepted via bitcoin:1Mad8TxTqxKnMiHuZxArFvX8BuFEB9nqX2 and PayPal:Protiguous@Protiguous.com
//
// ====================================================================
// Disclaimer: Usage of the source code or binaries is AS-IS.
// No warranties are expressed, implied, or given.
// We are NOT responsible for Anything You Do With Our Code.
// We are NOT responsible for Anything You Do With Our Executables.
// We are NOT responsible for Anything You Do With Your Computer.
// ====================================================================
//
// Contact us by email if you have any questions, helpful criticism, or if you would like to use our code in your project(s).
// For business inquiries, please contact me at Protiguous@Protiguous.com.
//
// Our software can be found at "https://Protiguous.Software/&quot;
// Our GitHub address is "https://github.com/Protiguous&quot;.
//
// File "ExampleUsingABetterClassDispose.cs" last formatted on 2020-11-07.
#nullable enable
namespace Librainian.Tests {
using System;
using System.IO;
using Utilities;
public class ExampleUsingABetterClassDispose : ABetterClassDispose {
private MemoryStream? _memoryStream = new MemoryStream();
private SysComObject? _sysComObject = new SysComObject();
public ExampleUsingABetterClassDispose() => this._sysComObject?.ReserveMemory();
public override void DisposeManaged() {
using ( this._memoryStream ) {
this._memoryStream = null;
}
base.DisposeManaged();
}
public override void DisposeNative() {
this._sysComObject?.ReleaseMemory();
this._sysComObject = null;
base.DisposeNative();
}
}
/// <summary>
/// A fake COM interface object.
/// </summary>
public class SysComObject {
public void ReleaseMemory() {
throw new NotImplementedException( "Not actual code." );
}
public void ReserveMemory() {
throw new NotImplementedException( "Not actual code." );
}
}
}
Categories
C# Tasks

Processing Tasks in Order of Completion

Disclaimer: I acknowledge this method was obtained from another blog; I’m pretty sure it was Stephen Toub’s, but I cannot seem to find his post again.

But here are my modified versions of his Interleaved() method.

#nullable enable

	using System;
	using System.Collections.Concurrent;
	using System.Collections.Generic;
	using System.Diagnostics;
	using System.Linq;
	using System.Threading;
	using System.Threading.Tasks;
	using JetBrains.Annotations;

	public static class TaskExtensions {

		/// <summary>
		/// Return tasks in order of completion.
		/// </summary>
		/// <param name="tasks"></param>
		/// <returns></returns>
		public static IEnumerable<Task<Task>> InOrderOfCompletion( this IEnumerable<Task> tasks ) {
			var inputTasks = tasks.ToList();

			var buckets = new TaskCompletionSource<Task>[ inputTasks.Count ];
			var results = new Task<Task>[ buckets.Length ];

			for ( var i = 0; i < buckets.Length; i++ ) {
				buckets[ i ] = new TaskCompletionSource<Task>();
				results[ i ] = buckets[ i ].Task;
			}

			var nextTaskIndex = -1;

			void Continuation( Task completed ) {
				var bucket = buckets[ Interlocked.Increment( ref nextTaskIndex ) ];
				bucket.TrySetResult( completed );
			}

			foreach ( var inputTask in inputTasks ) {
				inputTask?.ContinueWith( Continuation, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default );
			}

			return results;
		}

		/// <summary>
		/// Return tasks in order of completion.
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="tasks"></param>
		/// <returns></returns>
		[ItemNotNull]
		[NotNull]
		public static IEnumerable<Task<Task<T>>> InOrderOfCompletion<T>( this IEnumerable<Task<T>> tasks ) {
			var inputTasks = tasks.ToList();

			var buckets = new TaskCompletionSource<Task<T>>[ inputTasks.Count ];
			var results = new Task<Task<T>>[ buckets.Length ];

			for ( var i = 0; i < buckets.Length; i++ ) {
				buckets[ i ] = new TaskCompletionSource<Task<T>>();
				results[ i ] = buckets[ i ].Task;
			}

			var nextTaskIndex = -1;

			void Continuation( Task<T> completed ) {
				var bucket = buckets[ Interlocked.Increment( ref nextTaskIndex ) ];
				bucket.TrySetResult( completed );
			}

			foreach ( var inputTask in inputTasks ) {
				inputTask?.ContinueWith( Continuation, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default );
			}

			return results;
		}

		/// <summary>
		/// Return tasks in order of completion.
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="tasks"></param>
		/// <returns></returns>
		[ItemNotNull]
		[NotNull]
		public static IEnumerable<Task<Task<T>>> InOrderOfCompletion<T>( this IDictionary<TimeSpan, Task<T>> tasks ) {
			var inputTasks = tasks.ToList();

			var buckets = new TaskCompletionSource<Task<T>>[ inputTasks.Count ];
			var results = new Task<Task<T>>[ buckets.Length ];

			for ( var i = 0; i < buckets.Length; i++ ) {
				buckets[ i ] = new TaskCompletionSource<Task<T>>();
				results[ i ] = buckets[ i ].Task;
			}

			var nextTaskIndex = -1;

			void Continuation( Task<T> completed ) {
				var bucket = buckets[ Interlocked.Increment( ref nextTaskIndex ) ];
				bucket.TrySetResult( completed );
			}

			foreach ( var inputTask in inputTasks ) {
				inputTask.Value?.ContinueWith( Continuation, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default );
			}

			return results;
		}

	}

And here is my test code.

	public static class Examples {

		public static async Task TestsInOrderOfCompletion( CancellationToken token ) {
			var rng = new Random();

			//Add to the list, out of "order"..
			var tasks = new ConcurrentDictionary<TimeSpan, Task<String>> {
				[ TimeSpan.FromSeconds( 3 ) ] = Task.Delay( TimeSpan.FromSeconds( 3 ), token ).ContinueWith( _ => "3 seconds", token ),
				[ TimeSpan.FromSeconds( 1 ) ] = Task.Delay( TimeSpan.FromSeconds( 1 ), token ).ContinueWith( _ => "1 second", token ),
				[ TimeSpan.FromSeconds( 2 ) ] = Task.Delay( TimeSpan.FromSeconds( 2 ), token ).ContinueWith( _ => "2 seconds", token ),
				[ TimeSpan.FromSeconds( 5 ) ] = Task.Delay( TimeSpan.FromSeconds( 5 ), token ).ContinueWith( _ => "5 seconds", token ),
				[ TimeSpan.FromSeconds( 8 ) ] = Task.Delay( TimeSpan.FromSeconds( 8 ), token ).ContinueWith( _ => "8 seconds", token ),
				[ TimeSpan.FromSeconds( 7 ) ] = Task.Delay( TimeSpan.FromSeconds( 7 ), token ).ContinueWith( _ => "7 seconds", token ),
				[ TimeSpan.FromSeconds( 9 ) ] = Task.Delay( 1000, token ).ContinueWith( _ => "9 seconds", token ),
				[ TimeSpan.FromSeconds( 10 ) ] = Task.Delay( 1000, token ).ContinueWith( _ => "10 seconds", token ),
				[ TimeSpan.FromSeconds( 4 ) ] = Task.Delay( 1000, token ).ContinueWith( _ => "4 seconds", token )
			};

			//Add a few more to the list, also in "random" order..
			for ( var i = 0; i < 25; i++ ) {
				var millisecondsDelay = rng.Next( 10000 );
				var task = Task.Delay( millisecondsDelay, token ).ContinueWith( _ => $"{millisecondsDelay / 1000.0:F4}", token );   //return how many milliseconds we just delayed
				tasks[ TimeSpan.FromMilliseconds( millisecondsDelay ) ] = task;
			}

			foreach ( var bucket in tasks.InOrderOfCompletion() ) {
				try {
					var task = await bucket.ConfigureAwait( false );
					var result = await task.ConfigureAwait( false );
					Console.WriteLine( $"{DateTime.Now:hh:mm:ss}, TaskId #{task.Id:N0}, {result} ms" );

				}
				catch ( OperationCanceledException ) { }

				catch ( Exception exception ) {
					Debug.WriteLineIf( Debugger.IsAttached, exception.ToString() );
				}
			}

		}

	}
Categories
Articles C# Developers

The 4 pillars of OOP (Object Oriented Programming) summed up in my own words.

Encapsulation – The process of hiding internal data away from other classes.

Abstraction – The process of hiding irrelevant details while providing a feature.
(with the side effect of reducing the code complexity.)

Inheritance – The process of providing properties and methods to derived classes.

Polymorphism – The ability of a derived class to take on different behaviors than the parent class provides.

Categories
C#

Magical Methods in C#

Here is a very well written article about various capabilities in C# written by CEZARY PIĄTEK.
The Magical Methods in C#

Categories
C#

Curly {braces} Matter!

Blocks like “if“, “for“, “while“, and “using” (and others) should always use the curly braces “{” and “}“.

Code is for humans to read, and compilers to compile. Right?

By properly adding these braces ahead of time before they are needed, you future-proof the code and make the code’s intention (the logic) clear to any future programmer (including yourself).

This is not from an OCD formatting-enthusiast perspective. This is from decades of experience with C# and other {}-like languages.

Sure, one liners do work and they do reduce the total count of lines, but they are prone to bugs that are not immediately apparent to other programmers, compilers, code formatters, or via indentation.

If you use them, that is fine. Just be aware of the potential for issues in the future when someone edits the code.

BTW, If you can provide a reproducible example that causes C# code fail to compile, break, bug out, or crash by adding the proper braces, then please let me know! I’d greatly appreciate it.

Formatters cannot detect the original intent of the programmer. If even a single line of logic is missed (or ran when it should not), then the results of the function, method, or even the whole program could be affected.

Please, Do not write code to the lowest common denominator.

(I’ll link a gist if I ever get a better example completed.)
Here is a simplified example.

public static void RolRorRolRol( ref this UInt64 ul, Int32 n ) {
	if ( n > 2 )
		ul = ( ul << 3 ) | ( ul >> ( 64 - 3 ) );
	if ( ul < 10 )
		ul = ( ul << ( 64 - 4 ) ) | ( ul >> 4 );
	ul = ( ul << 5 ) | ( ul >> ( 64 - 5 ) );
	ul = ( ul << 6 ) | ( ul >> ( 64 - 6 ) );
}

Here is the “corrected” example.

public static void RolRorRolRol( ref this UInt64 ul, Int32 n ) {
	if ( n > 2 ) {
		ul = ( ul << 3 ) | ( ul >> ( 64 - 3 ) );
	}

	if ( ul < 10 ) {
		ul = ( ul << ( 64 - 4 ) ) | ( ul >> 4 );
		ul = ( ul << 5 ) | ( ul >> ( 64 - 5 ) );
	}

	ul = ( ul << 6 ) | ( ul >> ( 64 - 6 ) );
}
Categories
C#

Ordering of static fields in C# matters

via Ordering of static fields in C# matters

The ordering of static fields does matter.
But per your examples, here is the pattern I always use:

public class Person {
    private static EmptyPerson _emptyPerson;
    public static Person Empty => _emptyPerson ?? ( _emptyPerson = new EmptyPerson() );
}

The allows the Empty value to be initialized once and read-only, yet still used many times.

It also hides away the requirements of the initialization (the value pulled from a database for example) from the public getter. We could even put the value into a Lazy<Person>().

And in C# 8 we now have the compound assignment!

public class Person {
    private static EmptyPerson _emptyPerson;
    public static Person Empty => _emptyPerson ??= new EmptyPerson();
}
Categories
C#

Writing xUnit Tests in .NET Core

RE: Writing xUnit Tests in .NET Core — Visual Studio Magazine

Very nice example and explanations!
They even show how to pass in multiple values to test with.

Thank you!

Categories
Benchmarking C#

Big-O Algorithm Complexity Cheat Sheet

via Big-O Algorithm Complexity Cheat Sheet (Know Thy Complexities!) @ericdrowell

Nice! Thanks!

Categories
C#

C# Async Tips & Tricks

via C# Async Tips & Tricks

Helpful material !

Categories
C#

What’s new in the .NET Framework 4.7.2!

The 4.7.2 .NET Framework has been released! You can now download the SDK and the runtime here.

What’s New in the .NET Framework (4.7.2 edition)