bookmark_borderAwait is just an Operator

In .NET, and C# in particular, “await” is an operator just like ++ or &&. You can create all sorts of custom awaitable objects and build custom awaitable expressions.

Here is the simplest of examples!

Lets start by defining a task. A task needs to implement a single method:

  • GetAwaiter()
    • Returns an Awaiter. We will get to this next, its also got a schema to implement.
/// <summary>
/// A simple task.
/// </summary>
public class SimpleTask
{
    /// <summary>
    /// Gets the simple awaiter for the task.
    /// </summary>
    /// <returns>The awaiter.</returns>
    public SimpleAwaiter GetAwaiter()
    {
        return new SimpleAwaiter();
    }
}

Now for the Awaiter. The awaiter needs a few things defined:

  • GetResult()
    • Gets the result of the task.
    • Can be a void or non-void method.
  • IsCompleted
    • A property which returns a value indicating whether a task has completed. Ours is synchronous, so this always returns true.
  • ICriticalNotifyCompletion or INotifyCompletion
    • OnCompleted(Action continuation)
      • Called when returning from an async completion. If ICriticalNotifyCompletion is not implemented, then this will also be invoked on a synchronous completion.
    • UnsafeOnCompleted(Action continuation)
      • Only available if ICriticalNotifyCompletion is implemented, and will be invoked on a synchronous completion of the task. OnCompleted will not be called.
using System;
using System.Runtime.CompilerServices;

public class SimpleAwaiter : ICriticalNotifyCompletion, INotifyCompletion
{
    /// <summary>
    /// Our task never runs async, so its always completed.
    /// </summary>
    public bool IsCompleted => true;

    /// <summary>
    /// Our task doesnt return anything, so this can be a void method, 
    /// but lets return something so we have something to await.
    /// </summary>
    public string GetResult() => "Hello World";

    public void OnCompleted(Action continuation)
    {
        // OnCompleted is called on returning from an async completion.
        throw new NotImplementedException();
    }

    public void UnsafeOnCompleted(Action continuation)
    {
        // UnsafeOnCompleted is called after a sync completion.
        continuation();
    }
}

Heres an example of how this can all work!

class Program
{
    public static async Task Main(string[] args)
    {
        Console.WriteLine(await new SimpleTask());
    }
}

Give it a shot! The result will be “Hello World” in the console.

A good place to check for more information is the C# language reference: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/expressions#await-expressions

bookmark_borderDebugging a Simple C# Source Generator

Brand new to the world of C# is the concept of a source generator. A compiler extention which lets you inject code into your build before compilation. This was possible before by plugging custom build targets into the build system, but now you’ll get access to Roslyn’s syntax tree as you do it!

Prerequisites

Microsoft’s own blog will have better information, but the purpose of this post is to demonstrate how to debug. Source generators are a little strange, since they run as you build… not as you are actually debugging.

Debugging

Since the feature is still in preview, debugging is tough. The easiest way is to add a “Debugger.Launch()” in the Initialize method of the source generator. Here is an example with a very simple source generator.

namespace SimpleSourceGenerator
{
    using Microsoft.CodeAnalysis;
    using Microsoft.CodeAnalysis.CSharp;
    using Microsoft.CodeAnalysis.Text;
    using System.Diagnostics;
    using System.Text;

    /// <summary>
    /// Debuggable source generator.
    /// </summary>
    [Generator]
    internal class DebuggableSourceGenerator : ISourceGenerator
    {
        public void Execute(SourceGeneratorContext context)
        {
            const string ClassName = "TestClass";

            // Define a class named "TestClass" in the namespace SimpleSourceGenerator.Generated
            var testClass = SyntaxFactory.CompilationUnit()
                .AddMembers(SyntaxFactory.NamespaceDeclaration(SyntaxFactory.IdentifierName("SimpleSourceGenerator.Generated"))
                    .AddMembers(SyntaxFactory.ClassDeclaration(ClassName)));

            // Add the test class to the output.
            context.AddSource(ClassName + ".cs", SourceText.From(testClass.NormalizeWhitespace().ToFullString(), encoding: Encoding.UTF8));
        }

        public void Initialize(InitializationContext context)
        {
            // Attach the debugger.
            Debugger.Launch();
        }
    }
}

This will launch the debugger ever time the source generate gets initialized… which is quite often, so its only useful if you’re actively developing the generator. To kick off the source generator, just build/rebuild the project which references it. (In this example that’s SimpleConsoleApp). You can attach the same window of Visual Studio that you’re currently developing in as the debugger.

For completeness, here is what the rest of a simple source generator project looks like.

namespace SimpleConsoleApp
{
    using System;
    // This is the namespace we defined in the source generator as the output.
    using SimpleSourceGenerator.Generated;

    class Program
    {
        static void Main(string[] args)
        {
            // This is the test class which gets generated by the source generator.
            var test = new TestClass();
        }
    }
}
<!-- SimpleSourceGenerator.csproj This is the project file for the source generator.-->
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
    <LangVersion>preview</LangVersion>
  </PropertyGroup>

  <PropertyGroup>
    <RestoreAdditionalProjectSources>https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet5/nuget/v3/index.json;$(RestoreAdditionalProjectSources)</RestoreAdditionalProjectSources>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="3.6.0-3.20207.2" PrivateAssets="all" />
    <PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.0.0-beta2.final" PrivateAssets="all" />
  </ItemGroup>
</Project>
<!-- SimpleConsoleApp.csproj This is a simple console app which references the source generator.-->
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <LangVersion>preview</LangVersion>
  </PropertyGroup>

  <ItemGroup>
    <ProjectReference Include="..\SimpleSourceGenerator\SimpleSourceGenerator.csproj"
                      ReferenceOutputAssembly="false"
                      OutputItemType="Analyzer" />
  </ItemGroup>

</Project>

bookmark_borderVMDX to VHD conversion

You can easily convert a VMWare VMDX file to a Microsoft VHD file using the “Microsoft Virtual Machine Converter“. The Command ‘ConvertTo-MvmcVirtualHardDisk’ transforms the VMWare disk into a Hyper-V Compatible disk.

Once the Microsoft Virtual Machine Converter is installed, you can load the commandlets into a powershell session:

Import-Module 'C:\Program Files\Microsoft Virtual Machine Converter\MvmcCmdlet.psd1'

Once you have that, a command like below will do the trick:

ConvertTo-MvmcVirtualHardDisk -SourceLiteralPath 'D:\VM\CNC Windows 7 Professional\Windows 7 Pro
fessional-cl1.vmdk' -DestinationLiteralPath 'D:\VM\CNC Windows 7 Professional Hyper-v\Windows 7 Professional-cl1.vhd' -V
hdType DynamicHardDisk -VhdFormat Vhd

Errors

Now, for the true purpose of this article. Sometimes, ‘ConvertTo-MvmcVirtualHardDisk’ will throw an error, because it can’t understand something in the descriptor of the .VMDX. An error like below…

ConvertTo-MvmcVirtualHardDisk -SourceLiteralPath 'D:\VM\CNC Windows 7 Professional\Windows 7 Pro
fessional-cl1.vmdk' -DestinationLiteralPath 'D:\VM\CNC Windows 7 Professional Hyper-v\Windows 7 Professional-cl1.vhd' -V
hdType DynamicHardDisk -VhdFormat Vhd
ConvertTo-MvmcVirtualHardDisk : The entry 1 is not a supported disk database entry for the descriptor.
At line:1 char:1
+ ConvertTo-MvmcVirtualHardDisk -SourceLiteralPath 'D:\VM\CNC Windows 7 ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : WriteError: (Microsoft.Accel...nversionService:DriveConversionService) [ConvertTo-MvmcVi
   rtualHardDisk], VmdkDescriptorParseException
    + FullyQualifiedErrorId : DiskConversion,Microsoft.Accelerators.Mvmc.Cmdlet.Commands.ConvertToMvmcVirtualHardDiskCommand

ConvertTo-MvmcVirtualHardDisk : One or more errors occurred.
At line:1 char:1
+ ConvertTo-MvmcVirtualHardDisk -SourceLiteralPath 'D:\VM\CNC Windows 7 ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : WriteError: (Microsoft.Accel...nversionService:DriveConversionService) [ConvertTo-MvmcVi
   rtualHardDisk], AggregateException
    + FullyQualifiedErrorId : DiskConversion,Microsoft.Accelerators.Mvmc.Cmdlet.Commands.ConvertToMvmcVirtualHardDiskCommand

Finding good instructions online for how to solve this were tough, and most included downloading another program. This script takes the VMDK file, and reads the 1024 byte file descriptor at offset 512, then writes it to a text file. It will open that file in notepad++, but you can use any editor you like. After editing the text file, save, and use the second half of the script to write it back into the VMDK. If the VMDK is very important to you, please make a copy, to make sure you can still access your data if something were to go wrong.

# Open VM-ware disk, read 1024 bytes at position 512
$vmdkFileName = 'D:\VM\CNC Windows 7 Professional\Windows 7 Professional-cl1.vmdk'
$vmdkFileStream = [System.IO.File]::Open($vmdkFileName, [System.IO.FileMode]::Open, [System.IO.FileAccess]::ReadWrite)
$vmdkFileStream.Position = 512

$bytes = [byte[]]::new(1024);
$vmdkFileStream.Read($bytes, 0, 1024)

# Write to a temp file
$tempPath = [System.IO.Path]::Combine([System.IO.Path]::GetTempPath(), [System.IO.Path]::GetTempFileName())
$tempfile = [System.IO.File]::OpenWrite($tempPath)
$tempfile.Write($bytes, 0, 1024)
$tempfile.Dispose()

# Open the editor. Wait for exit doesn't always seem to work for npp...
# Use whichever edit you like, it needs to show text, and also helpful if it can show whitespace/control characters
$editor = Start-Process 'C:\Program Files\Notepad++\notepad++.exe' -ArgumentList $tempPath -PassThru -Wait
$editor.WaitForExit()

# TODO, change what is causing the problem in the opened file.

Now, an editor will open. You will see the file descriptor. The error message will describe which line in the file is causing the issue. Commenting (with a ‘#’) that line out of the file did the trick for me. Save, and run this to write the contents back into the VMDK.

For example, my error was “ConvertTo-MvmcVirtualHardDisk : The entry 1 is not a supported disk database entry for the descriptor.” So I commented out the line: db.toolsInstallType = “1”.

# Read back the temp file
$tempfile = [System.IO.File]::OpenRead($tempPath)
$tempfile.Read($bytes, 0, 1024);
$tempfile.Dispose()

# Write back to the vmdk
$vmdkFileStream.Position = 512
$vmdkFileStream.Write($bytes, 0, 1024)

# Cleanup
$vmdkFileStream.Dispose();
del $tempPath

Then try the conversion again!. If the entry to change was ambiguous, and didnt work, you can run the same steps again to try different changes.

bookmark_borderImplementing a class at runtime with Reflection.Emit

This is a simple example of how an interface can by dynamically implemented at runtime using the System.Reflection.Emit namespace. We’ll start by defining a dynamic assembly, then defining a class which implements our test interface. This is how frameworks, like Moq, can create interface implementations for you, which is especially powerful for unit testing.

Here is the interface we will be working with.

/// <summary>
/// The test interface to implement.
/// </summary>
/// <remarks>
/// Make this public so that the new assembly can see it.
/// Or set the "InternalsVisibleTo" attribute on this assembly with the name of the new dynamic assembly.
/// </remarks>
public interface ITestInterface
{
    /// <summary>
    /// This method will be implemented as a no-op.
    /// </summary>
    void ImplementMeToDoNothing();

    /// <summary>
    /// This method will return a default integer.
    /// </summary>
    /// <returns>Zero.</returns>
    int ImplementMeToReturnDefaultInt();

    /// <summary>
    /// This method will throw a NotImplementedException.
    /// </summary>
    void ImplementMeToThrowAnException();

    /// <summary>
    /// This method will return the value argument.
    /// </summary>
    /// <param name="argument">The return value.</param>
    /// <returns>The argument.</returns>
    int ImplementMeToReturnMyArgument(int argument);
}

Here are some test method to better explain our goals.

[TestMethod]
public void EnsureDoNothingSucceeds()
{
    ITestInterface instance = CreateMock();
    instance.ImplementMeToDoNothing();
}

[TestMethod]
public void EnsureDefaultReturnsZero()
{
    ITestInterface instance = CreateMock();
    Assert.AreEqual(0, instance.ImplementMeToReturnDefaultInt());
}

[TestMethod]
public void EnsureThrowsNotImplementedException()
{
    ITestInterface instance = CreateMock();
    Assert.ThrowsException<NotImplementedException>(() => instance.ImplementMeToThrowAnException());
}

[TestMethod]
public void EnsureReturnsArgument()
{
    ITestInterface instance = CreateMock();
    Assert.AreEqual(12345, instance.ImplementMeToReturnMyArgument(12345));
}

So lets define the function which will create our mock. This will build a new assembly, and create a class which implements ITestInterface.

private static ITestInterface CreateMock()
{
    // Create a dynamic assembly and module.
    var assemblyName = new AssemblyName("TestAssembly");
    var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(name: assemblyName, access: AssemblyBuilderAccess.RunAndCollect);
    var moduleBuilder = assemblyBuilder.DefineDynamicModule(name: assemblyName.Name);

    // Define the class builder for the new type to implement the interface "ITestInterface"
    var classBuilder = moduleBuilder.DefineType(
        name: nameof(ITestInterface) + "_Implementation",
        attr: TypeAttributes.Class | TypeAttributes.Public,
        parent: typeof(object),
        interfaces: new[] { typeof(ITestInterface) });

    // We don't have anything special to do in the constructor, so define a default one.
    classBuilder.DefineDefaultConstructor(MethodAttributes.Public);

    {
        // Lets start with a method which doesn't do anything.
        var parentImplementMeToDoNothing = typeof(ITestInterface).GetMethod(nameof(ITestInterface.ImplementMeToDoNothing));

        // Define the method to implement 'ImplementMeToDoNothing'. It doesn't need to have 
        // the same name, but for simplicity sake, it does.
        var doNothingMethodBuilder = classBuilder.DefineMethod(
            name: nameof(ITestInterface.ImplementMeToDoNothing),
            attributes: MethodAttributes.Public | MethodAttributes.Virtual,
            returnType: typeof(void),
            parameterTypes: Type.EmptyTypes);

        // Get an IL generator and just return.
        var ilGenerator = doNothingMethodBuilder.GetILGenerator();
        ilGenerator.Emit(OpCodes.Ret);

        // Make the method as implementing the definition on the interface.
        classBuilder.DefineMethodOverride(doNothingMethodBuilder, parentImplementMeToDoNothing);
    }

    {
        // Now lets do the method which returns the default int.
        var parentImplementMeToReturnDefaultInt = typeof(ITestInterface).GetMethod(nameof(ITestInterface.ImplementMeToReturnDefaultInt));
        var defaultIntMethodBuilder = classBuilder.DefineMethod(
            name: nameof(ITestInterface.ImplementMeToReturnDefaultInt), 
            attributes: MethodAttributes.Public | MethodAttributes.Virtual, 
            returnType: typeof(int), 
            parameterTypes: Type.EmptyTypes);

        var ilGenerator = defaultIntMethodBuilder.GetILGenerator();
        ilGenerator.Emit(OpCodes.Ldc_I4_0);
        ilGenerator.Emit(OpCodes.Ret);

        classBuilder.DefineMethodOverride(defaultIntMethodBuilder, parentImplementMeToReturnDefaultInt);
    }

    {
        // Implement a method which throws a "NotImplementedException".
        var parentImplementMeToThrowAnException = typeof(ITestInterface).GetMethod(nameof(ITestInterface.ImplementMeToThrowAnException));
        var throwExceptionBuilder = classBuilder.DefineMethod(nameof(ITestInterface.ImplementMeToThrowAnException), MethodAttributes.Public | MethodAttributes.Virtual, typeof(void), Type.EmptyTypes);
        var ilGenerator = throwExceptionBuilder.GetILGenerator();

        // Load the string we are going to pass into the constructor of "NotImplementedException" onto the execution stack.
        ilGenerator.Emit(OpCodes.Ldstr, $"The method ImplementMeToThrowAnException is not implemented.");

        // Create a new NotImplementedException(string)
        ilGenerator.Emit(OpCodes.Newobj, typeof(NotImplementedException).GetConstructor(new[] { typeof(string) }));

        // Throw the exception
        ilGenerator.Emit(OpCodes.Throw);
        ilGenerator.Emit(OpCodes.Ret);

        classBuilder.DefineMethodOverride(throwExceptionBuilder, parentImplementMeToThrowAnException);
    }

    {
        // Implement a method which returns the argument.
        var parentImplementMeToReturnMyArgument = typeof(ITestInterface).GetMethod(nameof(ITestInterface.ImplementMeToReturnMyArgument));
        var implementReturnArgument = classBuilder.DefineMethod(nameof(ITestInterface.ImplementMeToReturnMyArgument), MethodAttributes.Public | MethodAttributes.Virtual, typeof(int), new[] { typeof(int) });
        var ilGenerator = implementReturnArgument.GetILGenerator();

        // Since this is a class method, arg0 is always "this". So arg1 is the first argument.
        ilGenerator.Emit(OpCodes.Ldarg_1);
        ilGenerator.Emit(OpCodes.Ret);

        classBuilder.DefineMethodOverride(implementReturnArgument, parentImplementMeToReturnMyArgument);
    }

    // Finish the type.
    var createdType = classBuilder.CreateType();

    // Create a new instance of the type we just created.
    return (ITestInterface)Activator.CreateInstance(createdType);
}

There it is, the implementation provides four different examples. Another implementation strategy is to create the implementations to execute a delegate, so that you can execute whatever you like.

bookmark_borderReflection.Emit Hello World for Beginners

Lets start by saying the Reflection.Emit is inherently one of the most complex portions of the C# language. You’ll be able to undermine everything that the .Net designers intended and create complex difficult to debug code which your coworkers will hate. This article demonstrates a simple “Hello World” program.

Here is a little background before getting started.

  • Intermediate Language: In the java world, this is called “byte code”. It is a high level assembly language, which .Net code is translated into, before being compiled into machine code.
  • Execution Stack: This is where .Net does it’s work. Variables and references are pushed onto and popped off of the execution stack during execution. This is how arguments are passed to method calls. The method arguments are pushed onto the execution stack, and popped off by the method call.

Lets get started with a simple demonstration of a new Assembly, new Module, and a simple global method which prints out “Hello World Global Method!”

// Define a new assembly, named "TestAssembly".
var assemblyName = new AssemblyName("TestAssembly");
var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndCollect);
var moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.Name);

// Define a new global method named "HelloWorld".
var globalMethod = moduleBuilder.DefineGlobalMethod(
    name: "HelloWorld",
    attributes: MethodAttributes.Public | MethodAttributes.Static,
    returnType: typeof(void),
    parameterTypes: Type.EmptyTypes);

// Get the IL (intermediate language) generator for the method, so we can start working with intermediate language.
var ilGenerator = globalMethod.GetILGenerator();

// Get the method info for "Console.WriteLine(string)";
var writeLine = typeof(Console).GetMethod(
    name: nameof(Console.WriteLine),
    bindingAttr: BindingFlags.Static | BindingFlags.Public,
    binder: Type.DefaultBinder,
    types: new[] { typeof(string) },
    modifiers: null);

// Load the string "Hello World Global Method!" onto the execution stack.
ilGenerator.Emit(OpCodes.Ldstr, "Hello World Global Method!");

// Call Console.Writeline(string). This will pop off the string we just loaded onto the execution stack.
ilGenerator.Emit(OpCodes.Call, writeLine);

// Return.
ilGenerator.Emit(OpCodes.Ret);

// Global functions must be "done" before the module can be officially created.
// This call will create/compile them all.
moduleBuilder.CreateGlobalFunctions();

// Get the method we just created
var resultingMethod = moduleBuilder.GetMethod("HelloWorld");

// Create a delegate. This method takes no arguments and doesn't return a value, so its the same as an "Action".
var resultingDelegate = (Action)resultingMethod.CreateDelegate(typeof(Action));

// Call it.
resultingDelegate();

This was a very simple method and creating a dynamic assembly was too much work. So here is an example of the same thing, but using the “DynamicMethod” class. “DynamicMethod” is powerful in those sort of scenario, when creating simple static methods.

// Define a new assembly, named "TestAssembly".
var assemblyName = new AssemblyName("TestAssembly");
var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndCollect);
var moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.Name);

// Define a new global method named "HelloWorld".
var globalMethod = moduleBuilder.DefineGlobalMethod(
    name: "HelloWorld",
    attributes: MethodAttributes.Public | MethodAttributes.Static,
    returnType: typeof(void),
    parameterTypes: Type.EmptyTypes);

// Get the IL (intermediate language) generator for the method, so we can start working with intermediate language.
var ilGenerator = globalMethod.GetILGenerator();

// Get the method info for "Console.WriteLine(string)";
var writeLine = typeof(Console).GetMethod(
    name: nameof(Console.WriteLine),
    bindingAttr: BindingFlags.Static | BindingFlags.Public,
    binder: Type.DefaultBinder,
    types: new[] { typeof(string) },
    modifiers: null);

// Load the string "Hello World Global Method!" onto the execution stack.
ilGenerator.Emit(OpCodes.Ldstr, "Hello World Global Method!");

// Call Console.Writeline(string). This will pop off the string we just loaded onto the execution stack.
ilGenerator.Emit(OpCodes.Call, writeLine);

// Return.
ilGenerator.Emit(OpCodes.Ret);

// Global functions must be "done" before the module can be officially created.
// This call will create/compile them all.
moduleBuilder.CreateGlobalFunctions();

// Get the method we just created
var resultingMethod = moduleBuilder.GetMethod("HelloWorld");

// Create a delegate. This method takes no arguments and doesn't return a value, so its the same as an "Action".
var resultingDelegate = (Action)resultingMethod.CreateDelegate(typeof(Action));

// Call it.
resultingDelegate();

Another option to consider, if your use case is just simple static methods, is to use the System.Linq.Expressions namespace. This will create much more readable code, with much better supported debugging ability. An Expression tree will also show you the C# code which is generated behind the scenes, so you don’t need to work in IL.

// Get the method info for "Console.WriteLine(string)";
var writeLine = typeof(Console).GetMethod(
    name: nameof(Console.WriteLine),
    bindingAttr: BindingFlags.Static | BindingFlags.Public,
    binder: Type.DefaultBinder,
    types: new[] { typeof(string) },
    modifiers: null);

// Generate a lamba expression, which calls writeline, passing a single constant argument.
var lambdaExpression = Expression.Lambda(
    body: Expression.Call(
        method: writeLine, 
        arg0: Expression.Constant("Hello World Expression!")
    ));

var resultingMethod = (Action)lambdaExpression.Compile();
resultingMethod();

Take a look at “lambdaExpression.ToString()”. In the debugger, you will see that the underlying code generated is: “{() => WriteLine(“Hello World Expression!”)}”

Theres a quick tutorial on Reflection.Emit! In most code, using this functionality of .Net is overkill, and will cause maintainability nightmares. The best way to learn this stuff is to write some C# code, which looks like the code you’re trying to generate, and use a decompiler to look at the resulting IL.

bookmark_borderPowershell Variable Scoping

Confusion caused by variable scoping is a constant source of errors in Powershell. Most importantly, when is a variable visible, but any changes aren’t visible outside of the current scope. This is especially common with inner functions.

Here is an example, declaring a variable in an outer function makes it visible to the inner function. But it is passed by copy, so updating it in the inner function does not make changes visible to the outer function.

function Outer
{
    $var1 = 1;
    
    function Inner
    {
        Write-Output "Inner: $var1"

        # This change will not be visible in the outer function
        $var1++;
        Write-Output "Inner: $var1"
    }

    Write-Output "Outer: $var1"
    Inner
    Write-Output "Outer: $var1"
}
Outer

# Output: 
# Outer: 1
# Inner: 1
# Inner: 2
# Outer: 1

One way to fix that, is to declare the variable either “AllScope”, or in the global namespace. “AllScope” would be more advisable, since AllScope variables are available in all child scopes, as opposed to everywhere.

function Outer
{
    $var1 = 1
    Set-Variable -Name allscope -Value 1 -Option AllScope
    $global:var3 = 1
    
    function Inner
    {
        Write-Output "Inner: var1:$var1 allscope:$allscope var3:$global:var3"

        # This change will not be visible in the outer function
        $var1++;
        $allscope++;
        $global:var3++;
        Write-Output "Inner: var1:$var1 allscope:$allscope var3:$global:var3"
    }

    Write-Output "Outer: var1:$var1 allscope:$allscope var3:$global:var3"
    Inner
    Write-Output "Outer: var:$var1 allscope:$allscope var3:$global:var3"
}
Outer

# Outputs:
# Outer: var1:1 allscope:1 var3:1
# Inner: var1:1 allscope:1 var3:1
# Inner: var1:2 allscope:2 var3:2
# Outer: var:1 allscope:2 var3:2

Here is a program which executes to show a bunch of other behaviors when it commends to appending values to an array.

$Global:GlobalLevelArray = @("Script!");
$ScriptLevelArray = @("Script!");

function OuterFunc
{
    param
    (
        $OuterFuncArrayArg
    )

    process
    {
        # Changes to global variables will always be visible
        $Global:GlobalLevelArray = $Global:GlobalLevelArray + "OuterFunc";

        # Notice that this will update the array at this scope,
        # but not outside of this function.
        $ScriptLevelArray = $ScriptLevelArray + "OuterFunc";

        # This will update the array at this scope,
        # but changes will not be accessible to the caller.
        $OuterFuncArrayArg = $OuterFuncArrayArg + "OuterFunc";

        # This variable is visible at this level, and to child functions.
        $OuterFuncArray = @("OuterFunc");

        # A variable at the local scope is the current scope, but will not be available to the child scope.
        $local:OuterFuncLocalArray = @("OuterFunc");

        # This variable is available an modifieable to all child functions
        # Changes by the child will be reflected in here.
        Set-Variable -Name OuterFuncAllScopes -Value @("OuterFunc") -Option AllScope

        function NestedFunc
        {
            param
            (
            )
            process
            {
                $Global:GlobalLevelArray = $Global:GlobalLevelArray + "NestedFunc";
                $ScriptLevelArray = $ScriptLevelArray + "NestedFunc";
                $OuterFuncArrayArg = $OuterFuncArrayArg + "NestedFunc";
                $OuterFuncArray = $OuterFuncArray + "NestedFunc";
                $local:OuterFuncLocalArray = $local:OuterFuncLocalArray + "NestedFunc";
                $OuterFuncAllScopes = $OuterFuncAllScopes + "NestedFunc";

                # This, even though its declared all the way down in this nested func, will be available everywhere.
                $global:NestedFuncGlobalArray = @("NestedFunc")

                Write-Output "`t`tNestedFunc:GlobalLevelArray -> $($Global:GlobalLevelArray -join ',')"
                Write-Output "`t`tNestedFunc:ScriptLevelArray -> $($ScriptLevelArray -join ',')"
                Write-Output "`t`tNestedFunc:OuterFuncArrayArg -> $($OuterFuncArrayArg -join ',')"
                Write-Output "`t`tNestedFunc:OuterFuncArray -> $($OuterFuncArray -join ',')"
                Write-Output "`t`tNestedFunc:OuterFuncLocalArray -> $($local:OuterFuncLocalArray -join ',')"
                Write-Output "`t`tNestedFunc:OuterFuncAllScopes -> $($OuterFuncAllScopes -join ',')"
                Write-Output "`t`tNestedFunc:NestedFuncGlobalArray -> $($global:NestedFuncGlobalArray -join ',')"
            }
        }

        NestedFunc

        $global:NestedFuncGlobalArray = $global:NestedFuncGlobalArray + "OuterFunc";

        Write-Output "`tOuterFunc:ScriptLevelArray -> $($ScriptLevelArray -join ',')"
        Write-Output "`tOuterFunc:OuterFuncArrayArg -> $($OuterFuncArrayArg -join ',')"
        Write-Output "`tOuterFunc:GlobalLevelArray -> $($Global:GlobalLevelArray -join ',')"
        Write-Output "`tOuterFunc:OuterFuncArray -> $($OuterFuncArray -join ',')"
        Write-Output "`tOuterFunc:OuterFuncLocalArray -> $($local:OuterFuncArray -join ',')"
        Write-Output "`tOuterFunc:OuterFuncAllScopes -> $($OuterFuncAllScopes -join ',')"
        Write-Output "`tOuterFunc:NestedFuncGlobalArray -> $($global:NestedFuncGlobalArray -join ',')"
    }
}


OuterFunc -OuterFuncArray $ScriptLevelArray

$global:NestedFuncGlobalArray = $global:NestedFuncGlobalArray + "Script!";


Write-Output "Script:ScriptLevelArray -> $($ScriptLevelArray -join ',')"
Write-Output "Script:GlobalLevelArray -> $($GlobalLevelArray -join ',')"

Write-Output "Script:OuterFuncLocalArray -> $($local:OuterFuncArray -join ',')"

# An AllScopes variable in a child scope will not be visible in the parent scope
Write-Output "Script:OuterFuncAllScopes -> $($OuterFuncAllScopes -join ',')"
Write-Output "Script:NestedFuncGlobalArray -> $($global:NestedFuncGlobalArray -join ',')"

The output of this progrom:

		NestedFunc:GlobalLevelArray -> Script!,OuterFunc,NestedFunc
		NestedFunc:ScriptLevelArray -> Script!,OuterFunc,NestedFunc
		NestedFunc:OuterFuncArrayArg -> Script!,OuterFunc,NestedFunc
		NestedFunc:OuterFuncArray -> OuterFunc,NestedFunc
		NestedFunc:OuterFuncLocalArray -> NestedFunc
		NestedFunc:OuterFuncAllScopes -> OuterFunc,NestedFunc
		NestedFunc:NestedFuncGlobalArray -> NestedFunc
	OuterFunc:ScriptLevelArray -> Script!,OuterFunc
	OuterFunc:OuterFuncArrayArg -> Script!,OuterFunc
	OuterFunc:GlobalLevelArray -> Script!,OuterFunc,NestedFunc
	OuterFunc:OuterFuncArray -> OuterFunc
	OuterFunc:OuterFuncLocalArray -> OuterFunc
	OuterFunc:OuterFuncAllScopes -> OuterFunc,NestedFunc
	OuterFunc:NestedFuncGlobalArray -> NestedFunc,OuterFunc
Script:ScriptLevelArray -> Script!
Script:GlobalLevelArray -> Script!,OuterFunc,NestedFunc
Script:OuterFuncLocalArray -> 
Script:OuterFuncAllScopes -> 
Script:NestedFuncGlobalArray -> NestedFunc,OuterFunc,Script!

bookmark_borderPowershell Infix to Postfix Conversion

A common programming problem and interview question is to take an equation in “infix” notation, and transform it into “postfix” notation.

Lets take this for example:
Infix: (1+2)*(3+4)
Postfix: 1 2 + 3 4 + *

There are a few cases to consider:

  • Numbers
  • Operators
  • Parenthesis

Numbers always appear in the same order which they are processed between infix and postfix, so not much special needs to happen there. Operators are a little more complicated,

Operators are a little more complex. They need to appear in the order which they should be evaluated. There are two things which affect this… parenthesis and the order of operations.

Take the example: 1 + 2 * 3. We always need the multiplication to be evaluated before the addition. There is a simple rule. Every time you encounter an operator, push it onto a stack. At the next operator, if the top of the stack is of greater value, then the stack can be emptied into the output. If the top of the stack is of the same or lesser value, then add the current operator to the stack. This ensures that we will always append the operators which come earlier in the order of operations first.

A walkthrough of 1 + 2 * 3 - 4

Token | Stack | Output
  1   |       |                 <- 1 is a number, can go directly to output
  +   |       |   1             <- + is an operator, and the stack is empty, so push it onto the stack
  2   |   +   |   1             <- 2 is a number, can go directly to output
  *   |   +   |  1 2            <- * is an operator, but the operator on the top of the stack is less important
  3   |  * +  |  1 2            <- 3 is a number, it can go directly to output
  -   |  * +  | 1 2 3           <- - is an operator, less important than '*' which is on top of the stack,
                                    so empty the stack, and add the '-' onto the stack
  4   |   -   | 1 2 3 * +       <- 4 is a number, it can go directly to output
      |   -   | 1 2 3 * + 4     <- We're out of tokens, so empty the stack
      |       | 1 2 3 * + 4 -

Parenthesis can just be handle recursively. When a parenthesis is encountered, everything on the inside should be processed and sent to the output before continuing forward.

A walkthrough of 1 * (2 + 3)

Token | Stack | Output
  1   |       |             <- 1 is a number, can go directly to output
  *   |       |   1         <- + is an operator, and the stack is empty, so push it onto the stack
  (   |   *   |   1             <- Hit a parenthesis, so recurse and process the inside
  
  2   |          |          <- 2 is a number, can go directly to the output
  +   |       |   2         <- + is an operator, and the stack is empty, so push it.
  3   |   +   |   2         <- 3 is a number, can go directly to output
  )   |   +   |  2 3        <- Hit a close parenthesis, so empty the stack and unwinde from recursion
      |       | 2 3 +  
  
      |   *   | 1 2 3 +     <- Append the result of the recursive call
      |       | 1 2 3 + *   <- We're out of tokens, to empty the stack into the output

Here is some poweshell which takes this approach.

#
# Converts an infix expression into a postfix style expression
#
function InfixTo-Postfix
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory=$true, ValueFromPipeline = $true)][String]$InfixString
    )

    process
    {
        # Queue of all of the tokens we split the input string into
        # Numbers, operators, parenthesis
        $tokenQueue = [System.Collections.Queue]::new();

        # To build up numbers, in case they are more than a single digit.
        $currentNumber = '';

        # Go through each chacter in the string, and split it into tokens
        foreach($c in $InfixString.ToCharArray())
        {
            if ([char]::IsDigit($c))
            {
                # Build up the current digit/number
                $currentNumber += $c;
            }
            else
            {
                # Enqueue the current number into the token queue.
                if ($currentNumber  -ne '')
                {
                    $tokenQueue.Enqueue($currentNumber);
                    $currentNumber = '';
                }

                # Anything else which isn't whitespace is an operator (or a variable: a*b)
                if (-not [char]::IsWhiteSpace($c))
                {
                    $tokenQueue.Enqueue($c);
                }
            }
        }
        
        # If theres anything in the number we're working on, add that as well.
        if ($currentNumber  -ne '')
        {
            $tokenQueue.Enqueue($currentNumber);
        }       

        # Define the supported operators
        # Give each operator a weight, following the order of operations.
        $operators = @{};
        $operators[[char]'^'] = 2;
        $operators[[char]'*'] = 1;
        $operators[[char]'/'] = 1;
        $operators[[char]'+'] = 0;
        $operators[[char]'-'] = 0;

        # Helper function to handle everything underneath a set of parenthesis
        # Assumes that the open parenthsis has been removed from the token queue.
        function HandleParenthesis
        {
            # The output queue, this is where we'll write the result.
            $outQueue = @();

            # The operator stack.
            $operatorStack = [System.Collections.Stack]::new();

            # When the token queue is not empty
            while ($tokenQueue.Count -gt 0)
            {
                # Take the next item from the queue
                $item = $tokenQueue.Dequeue();
                
                if ($item -eq '(')
                {
                    # If it is an open parenthesis, we shoudl recurse.
                    $outQueue += HandleParenthesis
                }
                elseif ($item -eq ')')
                {
                    # On a close parenthesis, we're all done.
                    break;
                }
                elseif($operators.ContainsKey($item))
                {
                    # On an operator. Check to see if the top operator on the stack has a higher value than the current one.
                    # For example, if a '+' follows a '*', we need to do the '*' before the '+'.
                    if ($operatorStack.Count -gt 0 -and $operators[$operatorStack.Peek()] -gt $operators[$item])
                    {
                        while ($operatorStack.Count -gt 0)
                        {
                            $outQueue += $operatorStack.Pop();
                        }
                    }

                    # Push the current operator onto the stack
                    $operatorStack.Push($item);
                }
                else
                {
                    # Anything else, just append to the output.
                    $outQueue += $item;
                }
            }

            # If we have read all of the tokens we need to read, but there are still operators on the stack, finish popping them off.
            while ($operatorStack.Count -gt 0)
            {
                $outQueue += $operatorStack.Pop();
            }

            # Return the output.
            return $outQueue
        }   

        # Proecess the equation
        $outQueue = HandleParenthesis

        # The output queue is an array, so just turn it into a string
        return ($outQueue -join ' ');
    }
}
InfixTo-Postfix "x ^ y / (5 * z) + 10"
InfixTo-Postfix "(1+2)*(3+4)"
InfixTo-Postfix "1 ^ 2 ^ 3 ^ 4 ^ 5 * 6"

x y ^ 5 z * / 10 +
1 2 + 3 4 + *
1 2 3 4 5 ^ ^ ^ ^ 6 *

While we’re here lets do some golf.

function InfixTo-PostfixGolf($i){Set-Variable q -Value([regex]'([\d]+)|([\(\)\S])').Matches($i).Value -Option AllScope;function F{$o=@();$s=@();$e=@{'-'=0;'+'=0;'/'=1;'*'=1;'^'=2;};while($q){$t,$q=$q;switch($t){'('{$o+=F}')'{return $o+$s}({$e.ContainsKey($t)}){if($s-and$e[$s[0]]-gt$e[$t]){$o+=$s;$s=@()}$s=,$t+$s;}default{$o+=$t}}}$o+$s}(F)-join' '}

That’s 351 characters. It definitely seems like a sub-par solution, so I’ll be back.

It’s important to note that this solution takes a recursive approach to handling parenthesis. Another option is to push the parenthesis onto the stack, and use them as barriers when popping off operators. Aka, pop until you get back to the open parenthesis.

bookmark_borderSafely SetResult in TaskCompletionSource

tl/dr; When writing a library, or you don’t have control over the users, queue TaskCompletionSource.SetResult(…) calls in a new threadpool work item or inside of Task.Run. Since SetResult will execute anything awaiting it inline.

The C# TaskCompletionSource is an incredibly powerful part of the Task Parallel library. It’s an incredibly low level building block for asynchronous design, allowing for the creation of more advanced async structures. Its default behavior though, is unexpected and can lead to non trivial program bugs, performance issues, and deadlocks.

var source = new TaskCompletionSource<bool>();

// ...

source.SetResult(true);

An issue could arise when SetResult is called. By default, a TaskCompletionSource executes all continuations inline, when SetResult is called. This would be any case of (await, .ContinueWith). In the usual case, this is fine, but there are some scenarios when this is not expected.

The code sample below creates several tasks (Writer), which each create a “WorkItem”, and place it into a queue. The work item has a task completion source on it. Once the work item is enqueued, they each wait for the task completion source to be completed. Then They sleep for 1 second. Another task is spun up (Reader) which just waits for a WorkItem to be enqueued, dequeues it, and sets a result on the TaskCompletionSource. Ideally, the Reader should be able to dequeue every item very quickly, as its not really doing any work.

// main
TaskCompletionSourceThroughput.Run(
                
TaskCompletionSourceThroughput.TaskCompletionMode.PlainSetResult,
                count).Wait();
namespace Badflyer.TCSDeadlock
{
    using System;
    using System.Collections.Concurrent;
    using System.Diagnostics;
    using System.Linq;
    using System.Threading;
    using System.Threading.Tasks;

    internal class TaskCompletionSourceThroughput
    {
        public enum TaskCompletionMode
        {
            /// <summary>
            /// Just use regular old set result on a task completion source.
            /// </summary>
            PlainSetResult,

            /// <summary>
            /// Call set result, but create the TCS with TaskCreationOptions.RunContinuationsAsynchronously 
            /// </summary>
            SetResultWithAsyncContinuations,

            /// <summary>
            /// Call set result in a new threadpool action:  Task.Run(() => item.Completion.TrySetResult(item.Value));
            /// </summary>
            SetResultInTaskRun
        }

        private readonly int count;
        private readonly TaskCompletionMode mode;
        private readonly CancellationTokenSource cancellation;
        private readonly SemaphoreSlim gate;
        private readonly Stopwatch stopWatch;
        private readonly ConcurrentQueue<WorkItem<string>> workItems;

        private TaskCompletionSourceThroughput(TaskCompletionMode mode, int count)
        {
            this.count = count;
            this.mode = mode;
            this.cancellation = new CancellationTokenSource();
            this.gate = new SemaphoreSlim(0);
            this.stopWatch = Stopwatch.StartNew();
            this.workItems = new ConcurrentQueue<WorkItem<string>>();
        }

        /// <summary>
        /// Runs the test.
        /// </summary>
        /// <param name="mode">How to complet the task completion source during the test.</param>
        /// <param name="numberOfItems">The number of items to run with.</param>
        /// <returns>A task when the test is completed.</returns>
        internal static Task Run(TaskCompletionMode mode, int numberOfItems)
        {
            var test = new TaskCompletionSourceThroughput(mode, numberOfItems);
            return test.Run();
        }

        /// <summary>
        /// Run the test.
        /// </summary>
        /// <returns>An async that completes when the test does.</returns>
        private async Task Run()
        {
            // Start up these worker tasks which enqueue work items.
            var tasks = Enumerable.Range(0, count)
                .Select(i => Task.Run(() => Writer(i))).ToList();

            // Start up the reader task, which dequeues work items and complets them.
            var reader = Task.Run(Reader);

            await Task.WhenAll(tasks);
            this.cancellation.Cancel();
        }

        /// <summary>
        /// Reads each item from the workitems list, and completes it as quickly as it can.
        /// </summary>
        private async Task Reader()
        {
            var token = this.cancellation.Token;
            this.LogMessage("Starting Reader.");
            while (false == token.IsCancellationRequested)
            {
                try
                {
                    await gate.WaitAsync(token);
                }
                catch (OperationCanceledException)
                {
                    break;
                }

                this.workItems.TryDequeue(out var item);

                if (this.mode == TaskCompletionMode.SetResultInTaskRun)
                {
                    _ = Task.Run(() => item.Completion.TrySetResult(item.Value));
                }
                else
                {
                    item.Completion.TrySetResult(item.Value);
                }
            }

            this.LogMessage("Finished reader.");
        }

        /// <summary>
        /// Creates a new work item, enqueues it to the work items list, and waits for the reader task to complete the item.
        /// After the item is completed, it sleeps for 1 second.
        /// </summary>
        private async Task Writer(int index)
        {
            var item = new WorkItem<string>(this.mode, $"Finished Item {index}");
            this.workItems.Enqueue(item);
            this.gate.Release();

            var text = await item.Completion.Task;

            this.LogMessage(text);

            Thread.Sleep(1000);
        }

        /// <summary>
        /// Logs a message.
        /// </summary>
        /// <param name="message">The message.</param>
        private void LogMessage(string message)
        {
            Console.WriteLine("{0:0.000} [{1}] -> {2}", stopWatch.Elapsed.TotalSeconds, this.mode, message);
        }

        /// <summary>
        /// A simple work item class.
        /// </summary>
        /// <typeparam name="T">The type of the item result.</typeparam>
        private class WorkItem<T>
        {
            public WorkItem(TaskCompletionMode mode, T value)
            {
                this.Value = value;

                if (mode == TaskCompletionMode.SetResultWithAsyncContinuations)
                {
                    this.Completion = new TaskCompletionSource<T>(TaskContinuationOptions.RunContinuationsAsynchronously);
                }
                else
                {
                    this.Completion = new TaskCompletionSource<T>();
                }
            }

            public T Value { get; }

            public TaskCompletionSource<T> Completion;
        }
    }
}

The issue here will be caused in “Writer” during Thread.Sleep(1000). Its not exactly obvious, but since the TaskCompletionSource was being await, this part of the method is being run as a continuation to the completion source. Since by default, the TaskCompletionSource will queue and run everything inline when SetResult is called, this is actually running in the same thread as “Reader”.

TaskCompletionSource.SetResult doesn’t seem like it should be an expensive call, but it could be, depending on what the child decides to do. So in this case, Reader, which should be a super fast loop releasing a bunch of other threads, actually serializes the execution of all of the work items.

// Here is the output of the program
1.212 [PlainSetResult] -> Finished Item 2
2.214 [PlainSetResult] -> Finished Item 0
3.220 [PlainSetResult] -> Finished Item 3
4.222 [PlainSetResult] -> Finished Item 4
5.236 [PlainSetResult] -> Finished reader.

Now, task completion source does provide an option to specify TaskContinuationOptions. One of which is RunContinuationsAsynchronously. This does not seem to work as expected. This program can run with different arguments to utilize this feature.

// main

// This will create the TaskCompletionSource with the RunContinuationsAsynchronously parameter. 
// aka: new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously)

TaskCompletionSourceThroughput.Run(TaskCompletionSourceThroughput.TaskCompletionMode.SetResultWithAsyncContinuations).Wait();
// The results still show the output running serialized.

0.008 [SetResultWithAsyncContinuations] -> Starting Reader.
0.008 [SetResultWithAsyncContinuations] -> Finished Item 0
1.010 [SetResultWithAsyncContinuations] -> Finished Item 1
2.013 [SetResultWithAsyncContinuations] -> Finished Item 2
3.016 [SetResultWithAsyncContinuations] -> Finished Item 3
4.018 [SetResultWithAsyncContinuations] -> Finished Item 4
5.020 [SetResultWithAsyncContinuations] -> Finished reader.

For best performance, if you know that your continuations will be running lots of work, and you don’t want them to be serialized. You can always force the continuations to run in a different threadpool work item.

// Always run in a new threadpool thread.
Task.Run(() => taskCompletionSource.TrySetResult(result));

Doing this will add a lot of overhead if continuations are really quick, but will drastically improve performance if they are slow.

// main

// This will complete the task completion source task in a new threadpool thread.

TaskCompletionSourceThroughput.Run(TaskCompletionSourceThroughput.TaskCompletionMode.SetResultInTaskRun).Wait();
// Results

0.034 [SetResultInTaskRun] -> Starting Reader.
0.036 [SetResultInTaskRun] -> Finished Item 1
0.036 [SetResultInTaskRun] -> Finished Item 0
0.037 [SetResultInTaskRun] -> Finished Item 2
0.039 [SetResultInTaskRun] -> Finished Item 3
0.040 [SetResultInTaskRun] -> Finished Item 4
1.188 [SetResultInTaskRun] -> Finished reader

As you can see, these actually ended up running in a parallel nature.

The takeaway from this is that if you know that the functions awaiting your TaskCompletionSource are going to be doing heavy, slow work, or if you have no control over what they could be then be sure to call SetResult in a new threadpool thread. Another good example of this is Sytem.Net.Threading.SemaphoreSlim, which will always completion its waiting TaskCompletionSource in a new threadpool thread. https://referencesource.microsoft.com/#mscorlib/system/threading/SemaphoreSlim.cs,117283ce80a6dfb9

bookmark_borderTypescript Quadtree

Here is a simple quadtree implementation done in typescript! It is used to improve the performance of collision testing between all of the little circles which get displayed. (Clicking will add more circles).

The majority of the quadtree is implemented in a few classes. Here are the few notable ones to look out for.

  • QuadTree
  • QuadTreeNode
  • QuadTreeDrawer

More information on a quadtree can be found online, but the idea behind its use here is the same as that of a binary tree. We keep subdividing the canvas into fourths, so that we can lessen the area we need to consider during collision checking. 3D physics engines commonly use an oct-tree, which divides 3-dimensional space into 8ths.

Take a look at how collisions are processed to speed up the simulation (QuadTree.UpdateRecursive). Normally, you’d have to test each ball against every other ball at n^2 efficiency. With a quadtree, we can walk down each branch of the tree, only considering collisions between objects in the current tree node and parent nodes. The worst case scenario would be an object directly in the middle of the screen, which would be a child of the root quadtree node. It would need to be tested against every other object on the screen in this implemention.

# Here's an example (TL = topleft, TR = topright, BL = bottomleft, BR = bottomright)
----------- -----------|-----------|------------                          ------                                         
|                      |           |           |                         | root |    <---- Children = []                 
|                      |           |     a     |                          ------                                         
|                      |           |           |                      TL  TR  BL  BR                                     
                       ------------d------------                     /    |    |    \                                    
|                      |           |           |                   null   |   null   \                                   
|                      |           |     b     |                       -----         -----                               
|                      |           |           | Children = [ d ] ->  | L1  |       | L1  |    <------ Children = [ c ]  
----------- -----------------------|------------                       -----         -----                               
|                      |                       |                 TL  TR  BL  BR       TL  TR  BL  BR                     
|                      |                       |                /    |   |     \      /    |   |    \                    
|                      |                       |              null   |  null    \   null null null null                  
                                   c                               -----       -----                                     
|                      |                       |Children = [ a ]->| L2  |     | L2  | <------ Children = [ b ]           
|                      |                       |                   -----       -----                                     
|                      |                       |                                                                         
----------- -----------|----------- ------------                                                                         

# You can see that 'c' is on a completely different branch of the tree, so it doesn't need to be tested against a and b.
# a and b are also in different branches, so they also need to be tested.
# d is on the parent node of both a and b. It needs to be checked against both a and b.
/**
* This is a full implementation of the demo above. A lot of the stuff in here
* is just to make it show up on the screen. 
**/

/** Helper methods... */
class Helpers{
    /** Create a random color. But can define some constants. */
    static RandomColor(red : number = undefined, green : number = undefined, blue : number = undefined) : string {
        let r = red != undefined ? red : Math.random() * 256;
        let b = blue != undefined ? blue : Math.random() * 256;
        let g = green != undefined ? green : Math.random() * 256;
        let a = 0.4;

        return "rgba(" + r + "," + g + "," + b + "," + a + ")";
    }

    /** Remove an item from an array. */
    static Remove<T>(array : Array<T>, item : T){
        let index = array.indexOf(item);
        if(index == -1){
            throw "Element does not exist";
        }
        array.splice(index, 1);
    }
}

/** A  2 dimensional vector */
class Vector{
    public x : number;
    public y : number;

    constructor(x : number = 0, y : number = 0){
        this.x = x;
        this.y = y;
    }

    /** The distance between two vectors. */
    static dist(a : Vector, b : Vector) : number{
        return Math.sqrt(Math.pow(b.x - a.x, 2) + Math.pow(b.y - a.y, 2));
    }

    /** The dot product of two vectors. */
    static dot(a : Vector, b : Vector) : number{
        return a.x * b.x + a.y * b.y;
    }

    /** Add this to another vector. And a new vector with the product. */
    add(v : Vector) : Vector{
        return new Vector(v.x + this.x, v.y + this.y);
    }

    /** Subtract another vector from this one, and return a new vector with the product. */
    subtract(v : Vector) : Vector {
        return new Vector(this.x - v.x, this.y - v.y);
    }

    /** Multiply this vector by a scale, and return new vector with the product. */
    scale(scale : number){
        return new Vector(this.x * scale, this.y * scale);
    }

    // Copy this vector
    clone(){
        return new Vector(this.x, this.y);
    }

    /** Flip this vector around. */
    invert(){
        return new Vector(-1 * this.x, -1 * this.y);
    }

    /** Find the magnitude of this vector. */
    magnitude(){
        return Math.sqrt(this.x * this.x + this.y * this.y);
    }

    /** Normalize this vector to a length of 1. */
    normalize(){
        var mag = this.magnitude();
        return new Vector(this.x / mag, this.y / mag);
    }
}

/** The bounding circle class. */
class BoundingCircle{
    readonly position : Vector;
    readonly radius : number;

    constructor(position : Vector, radius : number){
        this.position = position;
        this.radius = radius;
    }

    topLeft() : Vector{
        return new Vector(this.position.x - this.radius, this.position.y - this.radius);
    }

    bottomRight() : Vector{
        return new Vector(this.position.x + this.radius, this.position.y + this.radius);
    }
}

/** Properties for physics */
class PhysicsProperties{
    position : Vector;
    velocity : Vector;
    acceleration : Vector;
    radius : number;
    mass : number;

    constructor(){
        this.position = new Vector();
        this.velocity = new Vector();
        this.radius = 0;
        this.mass = 100000;
        this.acceleration = new Vector();
    }
    
    /** Get the bounding circle for this object. */
    getBounds() : BoundingCircle{
        let circle = new BoundingCircle(this.position, this.radius);
        return circle;
    }

    /** A fully elastic collision between two circles. */
    processColission(other : PhysicsProperties)
    {
        let mcalc = other.mass * 2 / (this.mass + other.mass);

        let postDiff = this.position.subtract(other.position);
        let velocityDiff = this.velocity.subtract(other.velocity);
        let dot = Vector.dot(velocityDiff, postDiff);
        let magnitude = postDiff.magnitude();

        let scalar = mcalc * dot / (magnitude * magnitude);

        let v1 = this.velocity.subtract(postDiff.scale(scalar));
    
        mcalc = this.mass * 2 / (this.mass + other.mass);
        postDiff = other.position.subtract(this.position);
        velocityDiff = other.velocity.subtract(this.velocity);
        dot = Vector.dot(velocityDiff, postDiff);
        magnitude = postDiff.magnitude();
        scalar = mcalc * dot / (magnitude * magnitude);

        let v2 = other.velocity.subtract(postDiff.scale(scalar));

        this.velocity = v1;
        other.velocity = v2;
    }
}

/** Context which is passed on each update. */
class UpdateContext{

    /** The milliseconds since the last update. */
    public readonly deltaMilliseconds : number;

    /** The width of the land. */
    public readonly width : number;

    /** The height of the land. */
    public readonly height : number;

    /** The current time. */
    public readonly currentTime : number;

    constructor(deltaMS : number, width : number, height : number, currentTime : number){
        this.deltaMilliseconds = deltaMS;
        this.width = width;
        this.height = height;
        this.currentTime = currentTime;
    }
}

/** Context passed to the draw call. */
class DrawContext{

    /** The graphics context. */
    public readonly graphics : CanvasRenderingContext2D;

    constructor(context : CanvasRenderingContext2D){
        this.graphics = context;
    }
}

/** An updateable class. */
abstract class GameComponent{

    /** Update. Return true if this item needs to be deleted. */
    abstract update(context : UpdateContext) : boolean; 
    
    public physics : PhysicsProperties;
}

/** A draweable class. */
abstract class DrawableGameComponent extends GameComponent{
    abstract draw(context : DrawContext);
}

/** The physics controller. */
class PhysicsController extends GameComponent{
    
    readonly quadTree : QuadTree;
    readonly compontents : Array<PhysicsProperties>

    constructor(worldSize : Vector){
        super();
        this.quadTree = new QuadTree(8, worldSize);
        this.compontents = new Array<PhysicsProperties>();
    }

    /** Update the physics controller. Updates collisions and the quad tree */
    update(context : UpdateContext) : boolean{
        this.quadTree.Update();
        return false;
    }

    /** Add an item. */
    add(item : PhysicsProperties){
        this.compontents.push(item);
        this.quadTree.add(item);
    }
}

/** A ball on the screen. */
class Ball extends DrawableGameComponent{
    
    physics : PhysicsProperties;
    protected color : string;

    constructor(position : Vector, velocity : Vector, radius : number, color: string){
        super();
        this.physics = new PhysicsProperties();
        this.physics.position = position;
        this.physics.velocity = velocity;
        this.physics.radius = radius;
        this.physics.mass = Math.PI * radius * radius;
        this.color = color;
    }

    static CreateRandom(bounds: Vector, minRadius: number, maxRadius: number, minVelocity: Vector, maxVelocity: Vector)
    {
        let radius = Math.random() * (maxRadius - minRadius) + minRadius;
        let position = new Vector(Math.random() * (bounds.x - radius) + radius, Math.random() * (bounds.y - radius) + radius);
        let velocity = new Vector((Math.random() * (maxVelocity.x - minVelocity.x) + minVelocity.x) * (Math.random() > 0.5 ? 1 : -1 ), (Math.random() * (maxVelocity.y - minVelocity.y) + minVelocity.y) * (Math.random() > 0.5 ? 1 : -1 ));

        return new Ball(position, velocity, radius, Helpers.RandomColor(0, 0, undefined));
    }

    /** Update properties of the ball  */
    update(context : UpdateContext) : boolean{

        this.physics.velocity = this.physics.velocity.add(this.physics.acceleration);
        this.physics.acceleration = new Vector()

        /** Bounce off the walls. */
        if(this.physics.position.x - this.physics.radius <= 0 || this.physics.position.x + this.physics.radius >= context.width){
            this.physics.velocity.x *= -1;
        }

        if(this.physics.position.y - this.physics.radius <= 0 || this.physics.position.y + this.physics.radius >= context.height){
            this.physics.velocity.y *= -1;
        }

        // Update the movement
        this.physics.position = this.physics.position.add(this.physics.velocity.scale(context.deltaMilliseconds / 1000));
        return false;
    }

    /** Draw the ball */
    draw(context : DrawContext){

        context.graphics.beginPath();
        context.graphics.fillStyle = this.color;
        context.graphics.ellipse(
            this.physics.position.x,
            this.physics.position.y,
            this.physics.radius,
            this.physics.radius,
            0,
            0,
            Math.PI * 2);
        context.graphics.fill();
        context.graphics.closePath();
    }
}

/** A quadtree */
class QuadTree
{
    /** The maximum depth. */
    private readonly maxLevels : number;

    /** The root node. */
    private readonly root : QuadTreeNode;

    /** The size of the map. */
    private readonly size : Vector;

    /** The list of components. */
    private readonly components : Array<ComponentWrapper>

    public collisionsProcessed : number;

    constructor(maxLevels : number, size : Vector){
        this.maxLevels = maxLevels;
        this.root = new QuadTreeNode(1, this.maxLevels, null, new Vector(), size.clone());

        this.components = new Array<ComponentWrapper>();
    }

    /** Get the root node. */
    getRoot() : QuadTreeNode{
        return this.root;
    }

    /** Add a component to the tree. */
    add(component : PhysicsProperties){
        let wrapper = new ComponentWrapper(component, null);
        this.components.push(wrapper);
        this.getFittingNode(wrapper);
    }

    /** Update the entire tree. */
    Update(){
        for(let i = 0; i < this.components.length; i++){
            let component = this.components[i];

            this.root.GetNodeForComponent(component);
        }

        this.collisionsProcessed = 0;
        this.UpdateRecursive(this.root, new Array<PhysicsProperties>());
    }

    /** Update each node, test for collisions. */
    private UpdateRecursive(node : QuadTreeNode, list : Array<PhysicsProperties>){

        /** Base case, exit. */
        if(node == null){
            return;
        }

        /** For every component on the node. */
        for(let i = 0; i < node.components.length; i++){

            /** Process every other component on the node. */
            for(let c = i + 1; c < node.components.length; c++){
                this.TestCollision(node.components[i].component, node.components.component);
            }

            /** Process everything which is currently in the list. AKA on a parent node. */
            for(let c = 0; c < list.length; c++){
                this.TestCollision(node.components[i].component, list);
            }
        }

        /** Add everything to the list, so child nodes can check for collisions against them. */
        for(let i = 0; i < node.components.length; i++){
            list.push(node.components[i].component);
        }

        /** Update all child nodes. */
        this.UpdateRecursive(node.TopLeft, list);
        this.UpdateRecursive(node.BottomLeft, list);
        this.UpdateRecursive(node.TopRight, list);
        this.UpdateRecursive(node.BottomRight, list);

        /** Pop everything off the list to continue upwards. */
        for(let i = 0; i < node.components.length; i++){
            list.pop();
        }
    }

    /** Test a collision between two physics objexts. */
    private TestCollision(a : PhysicsProperties, b : PhysicsProperties)
    {
        let boundsA = a.getBounds();
        let boundsB = b.getBounds();

        let dist = Vector.dist(boundsA.position, boundsB.position);

        // Update the count.
        this.collisionsProcessed++;

        if(dist > boundsA.radius + boundsB.radius){
            return;
        }

        b.processColission(a);
    }

    /** This method is stupid. delete it. */
    private getFittingNode(component : ComponentWrapper) : QuadTreeNode{
        let node = this.root.GetNodeForComponent(component);
        return node;
    }
}

/** A node of the quad tree. */
class QuadTreeNode
{
    /** The child nodes. */
    private readonly cells : Array<QuadTreeNode>;

    /** The maximum depth. */
    private readonly maxDepth : number;

    /** The current depth */
    public readonly depth : number;

    /** The top left corner of the node. */
    public readonly topLeftBound : Vector;

    /** The bottom right corner of the node. */
    public readonly bottomRightBound : Vector;

    /** The center of the node. */
    public readonly centerBound : Vector;

    /** The components attached to the node. */
    public readonly components : Array<ComponentWrapper>

    /** The parent tree node. */
    public readonly parent : QuadTreeNode;

    constructor(depth : number, maxDepth : number, parent : QuadTreeNode, topLeftBound : Vector, bottomRightBound : Vector){
        this.depth = depth;
        this.maxDepth = maxDepth;
        this.cells = new Array(4);
        this.topLeftBound = topLeftBound;
        this.bottomRightBound = bottomRightBound;
        this.centerBound = new Vector((this.topLeftBound.x + this.bottomRightBound.x) / 2, (this.topLeftBound.y + this.bottomRightBound.y) / 2);
        this.components = new Array<ComponentWrapper>();
        this.parent = parent;
    }

    get TopLeft():QuadTreeNode{
        return this.cells[0];
    }

    get BottomLeft():QuadTreeNode{
        return this.cells[1];
    }

    get TopRight():QuadTreeNode{
        return this.cells[2];
    }

    get BottomRight():QuadTreeNode{
        return this.cells[3];
    }

    /** Get the deepest possible node for a component on the tree. 
     * Also prunes the tree if the component has left its node, and the node is empty.
    */
    GetNodeForComponent(wrapper : ComponentWrapper) : QuadTreeNode{
        let bounds = wrapper.component.getBounds();
        let tlNode = this.GetCellIndex(bounds.topLeft());
        let brNode = this.GetCellIndex(bounds.bottomRight());

        /** If we aren't at the max depth, and topleft/bottom right bounds fall within the same index,
         * then pass the responsibility to a child node. */
        if(tlNode == brNode &amp;&amp; this.depth < this.maxDepth){
            return this.GetOrCreateQuadTreeNode(tlNode).GetNodeForComponent(wrapper);
        }

        /** If the cell has just entered the current node. Then add to this collection, and prune the old node */
        if(wrapper.node != this)
        {
            this.components.push(wrapper);

            if(wrapper.node != null){
                Helpers.Remove(wrapper.node.components, wrapper);
                wrapper.node.Prune();
            }
        }

        /** Then set this as the current node. */
        wrapper.node = this;
        return this;
    }

    private GetCellIndex(point : Vector){
        let left = point.x < this.centerBound.x;
        let top = point.y < this.centerBound.y;

        // 0 2
        // 1 3
        return (top ? 0 : 1) + (left ? 0 : 2);
    }

    /** Removes the current tree node, if it is empty **/
    private Prune(){
        if(this.components.length > 0 || this.parent == null){
            return;
        }

        this.parent.PruneChild(this);
    }

    /** Removes the provided child node.  */
    private PruneChild(child : QuadTreeNode){
        let index = this.cells.indexOf(child);
        this.cells[index] = null;
        this.Prune();
    }

    /** Gets or creates a new quad tree node. */
    private GetOrCreateQuadTreeNode(index : number) : QuadTreeNode{
        if(this.cells[index] == null){
            this.cells[index] = new QuadTreeNode(
                this.depth + 1,
                this.maxDepth,
                this,
                new Vector(
                    index < 2 ? this.topLeftBound.x : this.centerBound.x,
                    index % 2 == 0 ? this.topLeftBound.y : this.centerBound.y),
                new Vector(
                    index < 2 ? this.centerBound.x : this.bottomRightBound.x,
                    index % 2 == 0 ? this.centerBound.y : this.bottomRightBound.y
                ));
        }

        return this.cells[index];
    }
}

/** Wrapper item used by the quad tree. Maps physics properties to a quad tree node. */
class ComponentWrapper{
    public component : PhysicsProperties;
    public node : QuadTreeNode;
    
    constructor(component : PhysicsProperties, node : QuadTreeNode){
        this.component = component;
        this.node = node;
    }
}

/** Draws the quad tree */
class QuadTreeDrawer extends DrawableGameComponent{ 
    physics : PhysicsProperties;

    private tree : QuadTree;
    constructor(tree : QuadTree){
        super();
        this.tree = tree;
        this.physics = null;
    }

    /** Update. Does nothing, but required by game component. */
    update(context : UpdateContext) : boolean{
        return false;
    }

    /** Draw the quad tree. */
    draw(context : DrawContext){
        context.graphics.beginPath();
        context.graphics.strokeStyle = 'red';
        this.drawRecursive(this.tree.getRoot(), context.graphics);
        context.graphics.closePath();
    }

    /** Draw a quad tree node. And its children. */
    private drawRecursive(node : QuadTreeNode, graphics : CanvasRenderingContext2D){
        if(node == null){
            return;
        }

        this.drawRecursive(node.TopLeft, graphics);
        this.drawRecursive(node.BottomLeft, graphics);

        graphics.strokeRect(node.topLeftBound.x, node.topLeftBound.y, (node.bottomRightBound.x - node.topLeftBound.x), (node.bottomRightBound.y - node.topLeftBound.y));

        this.drawRecursive(node.TopRight, graphics);
        this.drawRecursive(node.BottomRight, graphics);
    }
}

/** Runs update logic, and executes update/draw on components.  */
class GameController
{
    private drawInterval: number;
    private updateInterval: number;

    private graphics : CanvasRenderingContext2D;
    private canvas : HTMLCanvasElement;

    private components : Array<GameComponent>;
    private drawables : Array<DrawableGameComponent>
    private phsyicsController : PhysicsController;

    private previousContext : UpdateContext;

    constructor(canvas: HTMLCanvasElement){
        this.canvas = canvas;
        this.graphics = canvas.getContext("2d");

        this.components = new Array<GameComponent>();
        this.phsyicsController = new PhysicsController(new Vector(this.canvas.width, this.canvas.height));
        this.drawables = new Array<DrawableGameComponent>();

        this.drawables.push(new QuadTreeDrawer(this.phsyicsController.quadTree));
    }

    public run(){
        // The default update context
        this.previousContext = new UpdateContext(0, this.canvas.width, this.canvas.height, Date.now());
        if(!this.drawInterval){
            this.drawInterval = window.setInterval(() => this.draw(), 10);
        }
        if(!this.updateInterval){
            this.updateInterval = window.setInterval(() => this.update(), 10);
        }
    }

    public stop(){
        if(this.drawInterval){
            window.clearInterval(this.drawInterval);
            this.drawInterval = null;
        }
        if(this.updateInterval){
            window.clearInterval(this.updateInterval);
            this.updateInterval = null;
        }
    }

    public addComponent(component : GameComponent){
        this.components.push(component);

        if(component instanceof DrawableGameComponent){
            this.drawables.push(component);
        }

        if(component.physics != null){
            this.phsyicsController.add(component.physics);
        }
    }

    public clear(){
        for(let i = 0; i < this.components.length; i++){
            this.components.pop();
        }
    }

    get UpdateablesCount() : number{
        return this.components.length;
    }

    get DraweablesCount() : number{
        return this.drawables.length;
    }

    get Physics() : PhysicsController{
        return this.phsyicsController;
    }

    private update(){
        let now = Date.now();
        let updateContext = new UpdateContext(now - this.previousContext.currentTime, this.canvas.width, this.canvas.height, now);
        this.previousContext = updateContext;

        this.phsyicsController.update(updateContext);

        for(let i = this.components.length - 1; i >= 0; i--){
            if(this.components[i].update(updateContext)){
                this.components.splice(i, 1);
            }
        }
    }

    private draw(){

        let drawContenxt = new DrawContext(this.graphics);
        this.graphics.fillStyle = 'rgba(100, 100, 100, 0.2)';
        this.graphics.fillRect(0, 0, this.canvas.width, this.canvas.height);

        for(let i = this.drawables.length - 1; i >= 0; i--){
            this.drawables[i].draw(drawContenxt);
        }
    }
}

/** outputs diagnostic data to the screen. */
class Diagnostics extends DrawableGameComponent{

    private readonly gameController : GameController;
    private readonly startPosition : Vector;

    constructor(gameController : GameController){
        super()
        this.gameController = gameController;

        this.startPosition = new Vector(0, 16);
    }

    update(context : UpdateContext) : boolean{
        return false;
    }

    draw(context : DrawContext){
        context.graphics.beginPath();
        context.graphics.font = '16px monospaced'
        context.graphics.fillStyle = 'white';
        context.graphics.fillText("updateables: " + this.gameController.UpdateablesCount, this.startPosition.x, this.startPosition.y);
        context.graphics.fillText("draweables: " + this.gameController.UpdateablesCount, this.startPosition.x, this.startPosition.y + 16);
        context.graphics.fillText("collisions tested: " + this.gameController.Physics.quadTree.collisionsProcessed, this.startPosition.x, this.startPosition.y + 32);
        context.graphics.closePath();
    }    
}

/** Main class. */
class Main {

    private canvas : HTMLCanvasElement;
    private controller : GameController; 

    constructor(parent) {
        this.initializeCanvas(parent);
        this.controller = new GameController(this.canvas);
    }
    run() {
        this.controller.run();
    }
    stop() {
        this.controller.stop();
    }
    initializeTest() {
        this.AddRandomBall(5);
        //window.onkeydown = (event) => {
        //    if(event.charCode === 0){
        //        // Spacebar
        //        this.AddRandomBall();
        //    }
        //}
        this.canvas.onclick = (event) => {
            //let ball = new Ball(new Vector(event.offsetX - 15, event.offsetY - 15), new Vector(), 15, 'red')
            //this.controller.addComponent(ball);
            this.AddRandomBall(10);
        };
    }
    AddRandomBall(count = 20) {
        for (let i = 0; i < count; i++) {
            var ball = Ball.CreateRandom(new Vector(this.canvas.width, this.canvas.height), 2, 4, new Vector(30, 30), new Vector(180, 180));
            this.controller.addComponent(ball);
        }
    }
    EnableDiagnostics() {
        let diagnostic = new Diagnostics(this.controller);
        this.controller.addComponent(diagnostic);
    }
    initializeCanvas(parent) {
        this.canvas = document.createElement('canvas');
        this.canvas.width = parent.clientWidth;
        this.canvas.height = Math.floor(parent.clientWidth * 0.6);
        parent.appendChild(this.canvas);
    }
}
function Run(arg = null) {
    if (null === arg || undefined === arg) {
        arg = document.currentScript.parentElement;
    }
    let m = new Main(arg);
    m.initializeTest();
    m.EnableDiagnostics();
    m.run();
}

Run();

That should be all you need to get going.

bookmark_borderFizz Buzz in MSBuild

Here it is, what everyone has been waiting for.. an MS build implementation of fizz buzz.

<Project DefaultTargets="CleanupRecur"
    xmlns="http://schemas.microsoft.com/developer/msbuild/2003">  
    
    <PropertyGroup>
        <Currval Condition="'$(Currval)' == ''">1</Currval>
        <FileBaseName>$(Targets)</FileBaseName>
        <FileBaseName Condition="'$(FileBaseName)' == ''">recurfile</FileBaseName>
        <NextMsbuildFile>$(FileBaseName)-$(Currval).proj</NextMsbuildFile>
        <NextIndex>$([MSBuild]::Add($(Currval), 1))</NextIndex>
        <Mod3 Condition="$([MSBuild]::Modulo($(Currval), 3)) == 0">true</Mod3>
        <Mod5 Condition="$([MSBuild]::Modulo($(Currval), 5)) == 0">true</Mod5>
    </PropertyGroup>

    <Target Name="CopyFile">
        <Message Text = "$(NextIndex)" />
        <Copy Condition="$(Currval) < 100"
        SourceFiles="$(MSBuildProjectFile)"
        DestinationFiles="$(NextMsbuildFile)" />
    </Target>
    
    <Target Name="Fizz" DependsOnTargets="CopyFile">
        <Message Condition="'$(Mod3)' == 'true' AND '$(Mod5)' != 'true'" Text="Fizz" Importance="high"/>
        <Message Condition="'$(Mod5)' == 'true' AND '$(Mod3)' != 'true'" Text="Buzz" Importance="high"/>
        <Message Condition="'$(Mod3)' == 'true' AND '$(Mod5)' == 'true'" Text="FizzBuzz" Importance="high"/>
        <Message Condition="'$(Mod3)' != 'true' AND '$(Mod5)' != 'true'" Text="$(Currval)" Importance="high"/>
        <MSBuild Condition="$(Currval) < 100" Projects="$(NextMsbuildFile)" Targets="CleanupRecur" Properties="Currval=$(NextIndex)"></MSBuild>
    </Target>

    <Target Name="CleanupRecur" DependsOnTargets="Fizz">
        <Delete Files="$(NextMsbuildFile)" />
    </Target>
</Project>

You can run it as follows.

# Pass the minimal flag to avoid a bunch of extra msbuild output
msbuild /v:minimal .\fizz.proj
# The project works by getting the current value of the count from an environment variable "Currval".
# It evaluates the mod3 and mod5 of Currval

# It then makes a copy of its own project file, to avoid MSBuild detecting any circular dependencies
# It than executes MSBuild on the new project file, since it is a dependency, passing the incremented environment variable to the new project

# Then it cleans up the newly copied file

There you have it. A working implementation of fizzbuzz using MSBuild.