Exercise: Adding threads to an existing program

In this exercise you must add threads to an existing program.

Introduction

The program below finds and prints the smallest element in a number of arrays

using System;

namespace FindSmallest
{
    class Program
    {

        private static readonly int[][] Data = new int[][]{
            new[]{1,5,4,2}, 
            new[]{3,2,4,11,4},
            new[]{33,2,3,-1, 10},
            new[]{3,2,8,9,-1},
            new[]{1, 22,1,9,-3, 5}
        };

        private static int FindSmallest(int[] numbers)
        {
            if (numbers.Length < 1)
            {
                throw new ArgumentException("There must be at least one element in the array");
            }

            int smallestSoFar = numbers[0];
            foreach (int number in numbers)
            {
                if (number < smallestSoFar)
                {
                    smallestSoFar = number;
                }
            }
            return smallestSoFar;
        }

        static void Main()
        {
            foreach (int[] data in Data)
            {
                int smallest = FindSmallest(data);
                Console.WriteLine(String.Join(", ", data) + ": " + smallest);
            }
        }
    }
}

Make a new project in Visual Studio, copy-and-past the program into your project, and try to run the program.

Using ordinary threads

Refactor the program to use ordinary threads (new Thread(...)). Each thread should work on a single array finding the smallest element in that array.

Hint 1: Console.WriteLine(...) should be moved from the Main() method into the FindSmallest(...) method.

Hint 2: Use a lamba expression as a parameter to the Thread constructor.

Run the program again to check that it still works.

Use a thread pool with Task

Refactor the program to use a thread pool, NOT new Thread(...).

Hint: The threads in the pool are background theads. This means that they are killed as soon as the main program stops. You may have to add a Console.ReadLine() to the end of the main program to keep it from stopping to early. Or, even better, add Task.WaitAll(...).

Use Task with result

Yet another refactoring ... In this version I do not want to use a thread pool, but I want a Task which returns a result.

Basically I want the Task to retur a result so that the Console.WriteLine(...) can be moved back to the Main() method from the FindSmallest(...) method.

Some code fragments:

Extra: Thread with result

Go back to the Thread (not Task) version. Try to figure out a way to get the result from a Thread, just to see how hard(?) it is compare to Task.

Extra: Use other ways to compare

The method FindSmallest(...) finds the smallest element, but what if we want to find the largest or ...

Add a methods

private static int FindElement(int[] numbers, Comparison<int> comparison)
The parameter must be of the type Comparison<T>.

The extra parameter must be used to compare the elements. In this way you can find the smallest or the largest element, or ...

Unit test the method FindElement before you start using it in your program.