* Exceptions are problems that occur during the lifetime of the program
* Typical exceptions are IndexOutOfRangeException and NullReferenceException
* IndexOutOfRangeException occurs when trying to access an element of an object using an index greater than the number of elements in that object
* NullReferenceException occurs when trying to reference a variable that has not been assigned a value
* Typical exceptions are `IndexOutOfRangeException` and `NullReferenceException`
* `IndexOutOfRangeException` occurs when trying to access an element of an object using an index greater than the number of elements in that object
* `NullReferenceException` occurs when trying to reference a variable that has not been assigned a value
# Exceptions (continued)
## Checking for exceptions
* There should be some kind of system to check for these problems so that even if they do occur, the application does not crash
* For example, if a user tries to read from a file that does not exist, the user should be given an informative error message instead of closing the application
* *__finally__* block executes after a try-catch regardless of whether an exception occurred or not
* Useful for closing unmanaged objects like database connections or file streams
// Do this if connection / stream fails
```csharp
try
{
// Open a database connection or file stream
}
catch (SystemException e)
{
// Do this if connection / stream fails
}
finally
{
// Release the unmanaged resources from memory
}
```
}
## Exercise 1: Debugging Exceptions
finally
{
// Release the unmanaged resources from memory
}
# Exercise 1: Debugging Exceptions
<!-- _backgroundColor: #29366f -->
Create a savings calculator which asks the user for a target amount of money the user is aiming for (in integers), and the users monthly salary. For parsing, use the int.Parse() method instead of int.TryParse().
@ -117,129 +107,114 @@ Try your program with different user inputs. Try to intentionally break your pro
Handle the exceptions with exception handling, and inform the user of each exception with an appropriate message.
# Threads
## Threads
* You might have time consuming functionality in your program, like
* heavy algorithms and mathematical calculations, or
* You might have time consuming functionality in your program, like...
* heavy algorithms and mathematical calculations
* reading a large amount of data from a file
* You could also have some continuous stream of data being read, like
* You could also have some continuous stream of data being read, like...
* serial signal
* In case of time consuming methods, it might be a bad idea to wait for the execution to finish before continuing the main program
* This would show up to the user as the program being stuck
* At the very least, there could be some progress bar to indicate that the program hasn't crashed
* In the case of continuous execution, there needs to be some way to read the stream and execute the main program at the same time
# Threads (continued)
.NET supports __multithreading __ and classes to add new threads are included in the base class library
## Threads (continued)
using System.Threading;
* .NET supports *__multithreading__* and classes to add new threads are included in the base class library
```csharp
using System.Threading;
```
* Separate tasks can be executed simultaneously on separate *__threads__*
* Separate threads run on different cores in the processor
* All threads have access to the resources allocated to your program
Separate tasks can be executed simultaneously on separate __threads__
Separate threads run on different cores in the processor
All threads have access to the resources allocated to your program
Initialize a ThreadStart object with the method to be threaded as the argument:
public static void PrintInteger()
...
ThreadStart printIntegerStart = new ThreadStart(PrintInteger);
---
Initialize a Thread object with the ThreadStart object set as the argument, and start the new thread with Thread.Start() method:
* Initialize a `ThreadStart` object with the method to be threaded as the argument:
```csharp
public static void PrintInteger()
...
ThreadStart printIntegerStart = new ThreadStart(PrintInteger);
```
Thread printIntegerThread = new Thread(printIntegerStart);
* Initialize a `Thread` object with the `ThreadStart` object set as the argument, and start the new thread with `Thread.Start()` method:
```csharp
Thread printIntegerThread = new Thread(printIntegerStart);
printIntegerThread.Start();
```
printIntegerThread.Start();
## Thread example
# Threads - Example
<divclass='columns21'markdown='1'>
<divmarkdown='1'>
```csharp
class Program
{
public static void PrintInteger()
{
Console.WriteLine("Thread started.");
int val = 0;
while (true)
{
Thread.Sleep(100);
Console.WriteLine("Current value: " + val);
++val;
public static void PrintInteger()
{
Console.WriteLine("Thread started.");
int val = 0;
while (true)
{
Thread.Sleep(100);
Console.WriteLine("Current value: " + val);
++val;
}
}
static void Main(string[] args)
{
ThreadStart printIntegerStart = new ThreadStart(PrintInteger);
Console.WriteLine("Starting thread...");
Thread printIntegerThread = new Thread(printIntegerStart);
printIntegerThread.Start();
Console.WriteLine("Main thread continuing.");
}
}
```
</div>
<divmarkdown='1'>
}
The method prints a value, waits for $0.1\,\mathrm{s}$, increases the value, prints it again, etc.
static void Main(string[] args)
{
ThreadStart printIntegerStart = new ThreadStart(PrintInteger);
Console.WriteLine("Starting thread...");
Thread printIntegerThread = new Thread(printIntegerStart);
printIntegerThread.Start();
Console.WriteLine("Main thread continuing.");
}
}
The PrintInteger method prints a value, waits for 0.1sec, increases the value, prints it again and so on
The method keeps executing indefinitely, but the main thread continues execution as well
The method keeps executing indefinitely, but the main thread continues execution as well!
ThreadStart printIntegerStart = new ThreadStart(PrintInteger);
</div>
</div>
Console.WriteLine("Starting thread...");
## Threads (continued)
Thread printIntegerThread = new Thread(printIntegerStart);
* You can create as many threads as you like:
printIntegerThread.Start();
```csharp
ThreadStart printIntegerStart = new ThreadStart(PrintInteger);
Console.WriteLine("Starting thread...");
Thread printIntegerThread2 = new Thread(printIntegerStart);
Thread printIntegerThread = new Thread(printIntegerStart);
printIntegerThread.Start();
printIntegerThread2.Start();
Thread printIntegerThread2 = new Thread(printIntegerStart);
printIntegerThread2.Start();
Thread printIntegerThread3 = new Thread(printIntegerStart);
Thread printIntegerThread3 = new Thread(printIntegerStart);
printIntegerThread3.Start();
```
printIntegerThread3.Start();
## Exercise 2: Threaded Loading
<!-- _backgroundColor: #29366f -->
# Exercise 2: Threaded Loading
Create a method `public static void LoadData()` which simulates loading resources by printing progress from $0 \%$ to $100 \%$. Increase the progress in a loop with $1 \%$ increments. Use the `Thread.Sleep()` method to wait $10\,\mathrm{ms}$ between each increment.
Create a method public static void LoadData() which simulates loading resources by printing progress from 0% to 100%. Increase the progress in a loop with 1% increments. Use the Thread.Sleep() method to wait 10 ms between each increment.
Create a main loop where each time the user presses enter, the LoadData() method is executed on a separate thread.
Create a main loop where each time the user presses enter, the `LoadData()` method is executed on a separate thread.