Friday, February 2, 2018

nslookup like functionality from Powershell

Below is a Powershell script that takes a list of aliases that you want to lookup. For each item in the list it will output a line. Each line is tab separated and composed of the alias, the host name, and the ip address (first one if there are multiples). The output can be copy and pasted into Excel easily. Any errors will be shown in Red.

$aliases = @(
'www.apple.com',
'www.apple.co.uk'
)

foreach ($alias in $aliases)
{
    try
    {
        $entry = [System.Net.DNS]::GetHostEntry($alias)
        $tab = [char]9
        $hostname = $entry.HostName
        $ipAddress = $entry.AddressList[0].IPAddressToString
        Write-Host "$alias$tab$hostname$tab$ipAddress"
    }
    catch 
    {
        Write-Host "$alias could not be processed" -ForegroundColor Red
    }    
}

There are actually Powershell packages that implement nslookup, but they require something be installed, imports, dependencies, etc. The only dependency to run this is that C# be installed and System.Net.DNS be available.

Example output is:

www.apple.com e6858.dsce9.akamaiedge.net 2.20.214.243
www.apple.co.uk apple.co.uk 17.172.224.108

Tuesday, January 30, 2018

Getting Started with Angular and Visual Studio Code

Download and Install

Visual Studio Code (could use Visual Studio also or many other editors)
npm
Angular CLI
Angular Quickstart App

Setup

Open the View -> Interactive Terminal and type npm install to install all the packages specified in packages.json. Files will be put in node_modules which can safely be excluded from source control if desired since it can be rather large.


Running your app

Open the View -> Interactive Terminal and type npm start. This will build, start the web server, and open the browser.

Stopping your app

Go back to the Interactive Terminal and type Control-C and then Y to stop the web server.

Making Changes

If you make changes to the .html files the changes are automatically updated in the browser.

Friday, January 26, 2018

Blocking

Task.Delay()

If you are in an async method and you want to have it wait for a period of time before continuing your first thought might be to use Thread.Sleep(), but this would work the way you may think. Task.Delay() is what you want to use. Sleep just sleeps on the current thread which is the same as the thread that is calling the async method. Having an async method does NOT create threads unless the

Task.Run()

Task.Run() method is used to run a non-async method on another thread (from the thread pool by default). This is essentially just a background thread and has nothing to do with async. However since Task.Run() returns a Task you can await the result. This makes tracking the task and getting the result very easy.

Task.Run() is a good way to run a non-async method from an async method. There is overhead of spinning up an additional thread just to run this non-async code and then we would await the completion of the thread. This overhead is sometimes the only option if there is no async method available to call and all you have is a non-async method to call and you don't have access to change it.



Monday, October 16, 2017

Async in C#

Tips

A thread is a relatively heavy weight structure. 1 thread takes 1M of Stack Space. A task is NOT a thread. You can have multiple tasks running on a single thread (such as UI thread).

Task.Delay() is like Thread.Sleep(), but it is a Task that won't complete for a specified amount of time.

The keyword async is not part of the method signature. For example, it doesn't show up in interfaces. It is convention to add Async to the end of a method name though. This tell the reader it is async.

Return Task, not void.

await

Frees thread to do other things such as update UI, etc. Before await is called the stack trace is in the method you called it from which makes sense. The potentially surprising thing is that the line after the await does NOT have the same stack trace. It is now in the same thread, but clearly not in the same calling method anymore. This is because the compiler creates a state machine when the code is complied. It's building what would have been done by hand before we had the keyword await in C#.
  • await frees a thread while we wait for an operation to complete. For example, handle another request in web scenario, update UI thread in desktop scenario. 
  • It does NOT block the thread, it actually frees the thread to do something else. 
  • The execution is stopped until the task is complete. 
  • When the task is complete the thread gets focus and execution continues. This is similar in concept to a callback after something is complete.

Exception Handling

If there is an exception in an async method it will be thrown and can be caught as if it was not an async method. For example, a simple try-catch.

Tuesday, October 10, 2017

Free resources for Parallel Programming

Below is a list of free resources for parallel programming with .NET.

Microsoft's main site for all things parallel

Parallel Programming in the .NET Framework


Parallel Programming with Microsoft .NET: Design Patterns for Decomposition and Coordination on Multicore Architectures.




Passing data to a Task using parameter to avoid race condition

Requirements

Consider the scenario where you want to pass the current value of i to a new task that gets created in a for loop. We want each task to have a unique value of i (0...9).

The wrong approach (closures)

In general, it is a bad idea do use closures to pass data to a task when the value will change before the task starts. Below is a classic race condition such that the value of i is not read until the task starts, but before most of the tasks start all the tasks have been created. This will result in gotParamNow being equal to 10 (or any value really, but not what we intended).

for (int i=0; i<10; i++)
{
Task.Factory.StartNew( () =>
{
int gotParamNow = i;
}
);
}

The right approach (parameter)


If you want to pass data when the Task is CREATED (not when started as it would do when using closures) then you can pass the data to the StartNew method as shown below.

for (int i=0; i<10; i++)
{
Task.Factory.StartNew( (arg) =>
{
int gotParamNow = (int)arg;
},
i
);
}

In the code above the value i changes over time, so we want to pass it to the StartNew method so that when the task starts the data has the value that was passed to it and will result in each task having a unique value of i passed to it and thus gotParamNow will be unique as well.

Task Cancellation

Intro

When doing speculative work (starting multiple thread and only caring about the first result that comes back) these thread can take up valuable resources such as cpu or are long running, etc. We can just let these threads run to completion, but that won't free up the resources until they are done. Ideally once we have the result we want to cancel the threads once we don't need them to run anymore.

Cooperative Model

Creator passes a cancellation token, starts the task, later signals cancel, etc
Task monitors the token, if it is cancelled then it performs the cleanup and throws an exception.

Status on Task is set to "Canceled"


var cts = new CancellationTokenSource();
var token = ctx.Token;

Task t = Task.Factory.StartNew( () =>
{
try{
while (...)
{
// check for cancellation at start of each iteration
if (token.IsCancellationRequested)
{
// clean up
// NB: Make sure this exception bubbles up (as shown here) to the caller.
token.ThrowIfCancellationRequested();
}

// do the stuff would normally do here
...
}
}
catch (OperationCancelledException)
{
throw;
}
catch (Exception ex)
{
// handle exception
}
}, 
token // allows .NET to set status appropriately
);

// this may be invoked by a menu, keystroke, or other reason.
// This will trigger the canelling of the task.
// This would typically not be in the same location as the rest of the code here.
if (some condition occurs) {
cts.Cancel();
cts = new CancellationTokenSource(); // If need to re-run
}

try 

t.Wait(); // throws exception if cancelled
}
catch (AggregateException ae) {
ae = ae.Flatten();
foreach(var ex in ae.InnerExceptions)
{
if (ex is OperationCancelledException)
// do something (ignoring it now)
else
// handle exception (ex.Message will get error message)
}

}

Note: By passing the same token to several tasks will cause all the tasks to be cancelled when cts.Cancel() is called.

Caveat: Once Cancel() has been called on a task, the token passed to the Task cannot be used again once its status has been changed to Canceled. If you re-run the task you will need to create a new token as shown above. A good place is right after Cancel() is called.

Alternative approach

Use a global variable and check it to see if the task has been canceled. The trick in either implementation is to get the right level of polling. Too often will have performance implications and too little and cancelling won't be quick enough and waste resources.

Reference

Content is based on Pluralsight video called Introduction to Async and Parallel Programming in .NET 4 by Dr. Joe Hummel.