Monthly Archives: April 2019

Solution specific NuGet repository locations

Whether we’re making our code available to others or want to simply implement solution specific changes to our NuGet repository locations, we can create a NuGet.config file which is stored in the same location as our solution. Here’s a simple example of a NuGet.config which adds a local NuGet location

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <packageSources>
       <add key="Local" value="c:\Development\LocalNuGet" />
    </packageSources>
</configuration>

References

Configuring NuGet behavior

Tasks and CancellationTokens

We’re executing some code on a background thread using the Task API, for example let’s create a really simple piece of code where we loop on a task every second and call UpdateStatus to display the current iteration to some UI control, such as this

Task.Factory.StartNew(() =>
{
   for (var i = 1; i <= 100; i++)
   {
      UpdateStatus(i.ToString());
      Thread.Sleep(1000);
   }
});

Now this is fine, but what about if we want to call this code multiple times, stopping any previous iterations or we simply want a way to cancel the thread mid-operation.

Cancellation is a co-operative process, i.e. we can call the Cancel method on a CancellationTokenSource but we still need code within our task’s loop (in this case) to check if cancel has been called and then exit the loop.

The cancellation token is actually taken from CancellationTokenSource which acts as a wrapper for a single token (see References for information about this separation of concerns). So in our class we’d have the following member field

private CancellationTokenSource _cancellationTokenSource;

If the code which uses this token is called prior to completion then we’d potentially want to call the Cancel method on it and then dispose of it.

_cancellationTokenSource.Cancel();
_cancellationTokenSource.Dispose();

As mentioned, the separation of the token source and token means that when we execute a task we pass, not the token source, but a token take from the source, i.e.

var cancellationToken = _cancellationTokenSource.Token;
Task.Factory.StartNew(() =>
{
   // do something
}, cancellationToken);

The final piece of using the cancellation token is within our task, where we need to check if the cancellation token has been cancelled and if so, we can throw an exception using the following

cancellationToken.ThrowIfCancellationRequested();

Here’s a very simple example of using the cancellation token

public partial class MainWindow : Window
{
   private CancellationTokenSource _cancellationTokenSource;

   public MainWindow()
   {
      InitializeComponent();
   }

   private void Start_OnClick(object sender, RoutedEventArgs e)
   {
      DisposeOfCancellationTokenSource(true);

      _cancellationTokenSource = new CancellationTokenSource();
      var cancellationToken = _cancellationTokenSource.Token;

      UpdateStatus("Starting");
      Task.Factory.StartNew(() =>
      {
         for (var i = 1; i <= 100; i++)
         {
            cancellationToken.ThrowIfCancellationRequested();

            UpdateStatus(i.ToString());

            Thread.Sleep(1000);
         }
      }, cancellationToken)
      .ContinueWith(ca =>
      {
         DisposeOfCancellationTokenSource();
      }, TaskContinuationOptions.OnlyOnFaulted);
   }

   private void UpdateStatus(string status)
   {
      Status.Dispatcher.Invoke(() => Status.Content = status);
   }

   private void DisposeOfCancellationTokenSource(bool cancelFirst = false)
   {
      if (_cancellationTokenSource != null)
      {
         if (cancelFirst)
         {
            _cancellationTokenSource.Cancel();
            UpdateStatus("Cancel called");
         }
         _cancellationTokenSource.Dispose();
         _cancellationTokenSource = null;
         UpdateStatus("TokenSource Disposed");
      }
   }

   private void Stop_OnClick(object sender, RoutedEventArgs e)
   {
      DisposeOfCancellationTokenSource(true);
   }
}
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Button Grid.Row="0" Content="Start" Margin="10" Click="Start_OnClick"/>
        <Button Grid.Row="1" Content="Stop" Margin="10" Click="Stop_OnClick"/>
        <Label Grid.Row="2" Name="Status" Content=""/>
    </Grid>

References

Why CancellationToken is separate from CancellationTokenSource?
Task Cancellation
CancellationTokenSource.Dispose Method

Java’s Linq equivalent, Streams

I was working on a previous post on Java and GraphQL and wanted to use a Linq query. Java doesn’t have Linq but it does have something equivalent (in Java 8) called Stream. For the examples within this post we’ll create the following simple method for generating our test data

private static List<String> getData() {
   return Arrays.asList(
      "2", "2", "2", "4", "4", 
      "6", "7", "7", "9", "10");
}

Let’s look at some of the standard sort of functionality…

Distinct

We can get a distinct stream from our data using

Stream<String> distinct = getData()
   .stream()
   .distinct();

Selection/Filtering

If we want to filter our data to select only strings longer than one character, for example, then we can use the following

Stream<String> where = getData()
   .stream()
   .filter(s -> s.length() > 1);

Matching

There are several methods which return a Boolean, for example if all items in the Stream are of a certain value, or any of the values no matches, for example

boolean allMatch = getData()
   .stream()
   .allMatch(s -> s.contains("4"));

boolean anyMatch = getData()
   .stream()
   .anyMatch(s -> s.contains("4"));

boolean noneMatch = getData()
   .stream()
   .noneMatch(s -> s.contains("4"));

Map

In scenarios where we wish to change the data returned from a stream (i.e. like Select in Linq), for example we’ll simply loop through each item and return the length of each string as a Stream, we can use

Stream<Integer> select = getData()
   .stream()
   .map(String::length);

Reduce

If we want to take a stream and reduce it to a single value, for example taking our data and concatenating into a single String, we could use the following

String reduce = getData()
   .stream()
   .reduce("", (a, b) -> a + b);

The initial value “” in this case is a starting value for the reduced value, in this case we’re not wanting to prepend anything to our string. The result of the reduce is a String with the value 22244677910.

Creating an empty Stream

We can create an empty Stream (useful in those situations where we do not wish to return a null) using

Stream<String> empty = Stream.empty();

Iteration

We can iterate over the Stream using the forEach method, for example

getData()
   .stream()
   .forEach(s -> System.out.println(s));

Parallel Streams

We can also parallelize (is that a word) our Stream using the parallelStream, for example

Stream<Integer> parallel = getData()
   .parallelStream()
   .map(String::length);

As you’d expect the order or processing of the map in this instance is indeterminate.

Obviously there’s more to Stream than I’ve listed here, but you get the idea.

Creating a TaskScheduler

In my previous post, ExecutorService based multi-threading in Java, I looked at the ExectorService which allows us to create our own fixed size threadpool which can, at times, be extremely useful.

As part of a port of some Java code (which used the ExectorService) to C# I had a need for a similar class in .NET and came across the LimitedConcurrencyLevelTaskScheduler which is part of the Samples for Parallel Programming with the .NET Framework. The code and example of this class can also be found here, TaskScheduler Class.

The Task factory’s StartNew method comes with an overload which takes a TaskScheduler class and this is where the LimitedConcurrencyLevelTaskScheduler is used. For example

var taskScheduler = new LimitedConcurrencyLevelTaskScheduler(3);
var tsk = Task.Factory.StartNew(() =>
{
   // do something
}, 
CancellationToken.None, 
TaskCreationOptions.None, 
taskScheduler);

So, if we’re in a situation where we need to create a new TaskScheduler then we simply implement a TaskScheduler class, here’s the required overrides.

public class MyTaskScheduler : TaskScheduler
{
   protected override IEnumerable<Task> GetScheduledTasks()
   {
   }

   protected override void QueueTask(Task task)
   {
   }

   protected override bool TryExecuteTaskInline(
      Task task, bool taskWasPreviouslyQueued)
   {
   }
}

The QueueTask method is called when a Task is added to the scheduler. In the case of an implementation such as LimitedConcurrencyLevelTaskScheduler, this is where we add a task to a queue prior to executing the task.

TryExecuteTaskInline is called when trying to execute a task on the current thread, it’s passed a Boolean taskWasPreviouslyQueued which denotes whether the task has already been queued.

GetScheduledTasks is called to get an enumerable of the tasks currently scheduled within our TaskScheduler.

Optionally, we may wish to override the MaximumConcurrencyLevel property which stipulates the maximum concurrency level supported (i.e. number of threads), the default is MaxValue. Also where we might be maintaining a queue of tasks, we wold want to override the TryDequeue method for when the scheduler tries to remove a previously scheduled task.

Obviously implementing the TaskScheduler will also require the developer to handle any thread synchronization etc. within the implementation.