Thursday 31 December 2015

Performance tests

Code can always be optimized in terms of resources used. It makes sense adding performance tests when resources matter and their acceptable usage is a part of the requirements.

Resources can be time, memory, number of threads, sockets etc...but probably most measured are time and memory.

These tests are integration tests because:
- they rely on external factors (they are system- and hardware-dependent)
- asserted results can vary in time
- they can take much time to execute

An example of performance test is verifying that some algorithm performs some task within the acceptable time range.

There is a question on their consistency: e.g. the same algorithm takes more time to execute on slower machines so how to determine pass/fail criteria?



Further reading:
https://en.wikipedia.org/wiki/Software_performance_testing
http://www.dynatrace.com/en/javabook/performance-in-continuous-integration.html
http://stackoverflow.com/questions/751626/performance-testing-best-practices-when-doing-tdd
http://stackoverflow.com/questions/2870322/performance-testing-versus-unit-testing
http://stackoverflow.com/questions/457605/how-to-measure-code-performance-in-net
http://stackoverflow.com/questions/969290/exact-time-measurement-for-performance-testing
http://stackoverflow.com/questions/15181358/how-can-i-unit-test-performance-optimisations-in-c


Thursday 24 December 2015

DRY in action - Use lambda to fixate method's argument


In the following example we have a situation where Foo() calls Bar() multiple times. Within each Foo() call, it passes to Bar() different value for string argument but always the same value for int argument:

Output:


i = 123, s = test1
i = 123, s = test2
i = 123, s = test3
i = 456, s = test1
i = 456, s = test2
i = 456, s = test3


To avoid unnecessary repetition we can introduce one level of indirection - a lambda which calls Bar() and provides it string value via its own argument and int value via capturing argument passed to Foo(). After refactoring:

Output:


i = 123, s = test1
i = 123, s = test2
i = 123, s = test3
i = 456, s = test1
i = 456, s = test2
i = 456, s = test3


Monday 21 December 2015

OperationCanceledException vs TaskCanceledException when task is canceled


In my previous post, "How to cancel a Task", I mentioned that MSDN recommends throwing OperationCanceledException from a cancelled task. But the following example shows that canceling .NET methods makes them throw a different exception type - TaskCanceledException:

Output:


System.Threading.Tasks.TaskCanceledException: A task was canceled.
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Program.d__1.MoveNext()
Task.IsCanceled: True
Task.IsFaulted: False
Task.Exception: null


So why .NET does not follow its own rules? Why exception thrown in the example above was not OperationCanceledException?

I asked this question on SO and this is how I interpret the answer I got:

(1) System.OperationCanceledException class has been around longer than TPL. MSDN describes it as: "The exception that is thrown in a thread upon cancellation of an operation that the thread was executing." It is intended to be thrown from a thread in which operation is executed. .NET async API are actually synchronous operations (return Task, not marked as async). They don't have additional thread involved which makes OperationCanceledException not appropriate exception to be thrown.

(2) It is different to cancel a Task (setup of the engine which will execute "real work", user's operation) than to cancel operation itself. For example, we can pass already cancelled token to a task or can simply create already cancelled task. Operation and its thread are not started at all in these cases but if we await such task and catch OperationCanceledException we might think they were actually started. So it makes sense to use different type of the exception in these two different scenarios.

Example 1: Already canceled token is passed to task factory method:

Output:


System.Threading.Tasks.TaskCanceledException: A task was canceled.
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Program.d__1.MoveNext()
Task.IsCanceled: True
Task.IsFaulted: False
Task.Exception: null


Example 2: Awaiting task which is created as already canceled:

Output:


System.Threading.Tasks.TaskCanceledException: A task was canceled.
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNot
ification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at Program.d__1.MoveNext()
Task.IsCanceled: True
Task.IsFaulted: False
Task.Exception: null


From the points made above we can conclude that caller of the cancelable task can expect two types of exceptions:OperationCanceledException and TaskCanceledException. As the latter derives from the former, it is enough to handle OperationCanceledException if we want to handle the case of canceled task:




Further reading:
SO Q&A: OperationCanceledException VS TaskCanceledException when task is canceled
SO Q&A: Difference between OperationCanceledException and TaskCanceledException?
Andrew L Arnott: Recommended patterns for CancellationToken

Sunday 20 December 2015

How to cancel a Task


It is a good practice to offer users a chance to cancel some long-running operation. Such operation usually has to run asynchronously and in a TPL-based design is modeled as a method returning a Task.

Cancellation model requires some flag which is accessible by the caller and from inside the operation. Caller sets the flag when wants operation to be cancelled. Operation regularly checks the flag or is subscribed to the event "flag has been set" and if flag has been set, operation will stop doing the work. This model is in .NET abstracted with two types: CancellationTokenSource class and CancellationToken structure. Caller uses CancellationTokenSource to initiate cancellation and operation uses CancellationToken to check whether it has been cancelled.

When designing an API, if provision for operation cancellation is required, we have to add a CancellationToken to a list of method's arguments. API caller invokes CancellationTokenSource.Cancel method which sets CancellationToken.IsCancellationRequested to true. Target method checks this property and can either silently return or throw OperationCanceledException. The latter approach is better as only in this case returning task will come to Canceled state.

The following code depicts the whole process of task cancellation:

CancellationToken.ThrowIfCancellationRequested() method simply checks CancellationToken.IsCancellationRequested and if it's true, it throws OperationCanceledException. The output of the code above is:


.........System.OperationCanceledException: The operation was canceled.
   at System.Threading.CancellationToken.ThrowIfCancellationRequested()
   at MyService.d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Program.d__1.MoveNext()
Task.IsCanceled: True
Task.IsFaulted: False
Task.Exception: null


The following code shows that the await-ed task does not get aware that the task it holds got canceled if method silently returns on cancellation:

Output:

..........Task.IsCanceled: False
Task.IsFaulted: False
Task.Exception: null


Further reading:
Andrew Arnott - Recommended patterns for CancellationToken
MSDN: Task Cancellation

Saturday 19 December 2015

await VS Wait() when Task throws exception

await and Wait() are two versions of the operation "wait for the task to complete": one is asynchronous (non-blocking) and the other one is synchronous (blocking). They are both capable of capturing the exception thrown from the task but they behave in a different way when propagating exception information up the stack: they themselves throw different type of exception.


await (case 1) propagates the original exception so the output is:


System.ArgumentNullException: Value cannot be null.
   at Program.<>c.b__1_0()
   at System.Threading.Tasks.Task`1.InnerInvoke()
   at System.Threading.Tasks.Task.Execute()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Program.d__1.MoveNext()
Task.Status: Faulted
Task.IsFaulted: True
Task.Exception: System.AggregateException: One or more errors occurred. ---> System.ArgumentNullException: Value cannot be null.
   at Program.<>c.b__1_0()
   at System.Threading.Tasks.Task`1.InnerInvoke()
   at System.Threading.Tasks.Task.Execute()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Program.d__1.MoveNext()
   --- End of inner exception stack trace ---
---> (Inner Exception #0) System.ArgumentNullException: Value cannot be null.
   at Program.<>c.b__1_0()
   at System.Threading.Tasks.Task`1.InnerInvoke()
   at System.Threading.Tasks.Task.Execute()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Program.d__1.MoveNext()<---


Wait() (case 2) wraps original exception in System.AggregateException:


System.AggregateException: One or more errors occurred. ---> System.ArgumentNullException: Value cannot be null.
   at Program.<>c.b__1_0()
   at System.Threading.Tasks.Task`1.InnerInvoke()
   at System.Threading.Tasks.Task.Execute()
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at System.Threading.Tasks.Task.Wait()
   at Program.d__1.MoveNext()
---> (Inner Exception #0) System.ArgumentNullException: Value cannot be null.
   at Program.<>c.b__1_0()
   at System.Threading.Tasks.Task`1.InnerInvoke()
   at System.Threading.Tasks.Task.Execute()<---

Task.Status: Faulted
Task.IsFaulted: True
Task.Exception: System.AggregateException: One or more errors occurred. ---> System.ArgumentNullException: Value cannot be null.
   at Program.<>c.b__1_0()
   at System.Threading.Tasks.Task`1.InnerInvoke()
   at System.Threading.Tasks.Task.Execute()
   --- End of inner exception stack trace ---
---> (Inner Exception #0) System.ArgumentNullException: Value cannot be null.
   at Program.<>c.b__1_0()
   at System.Threading.Tasks.Task`1.InnerInvoke()
   at System.Threading.Tasks.Task.Execute()<---


Note that Task.Exception in both cases holds System.AggregateException. This difference comes from the desire of async-await implementers to keep use of await as simple as possible and to make its use to look like synchronous code as much as possible. System.AggregateException is not used in synchronous code (in non-TPL code) and we there always catch the first exception that is thrown from a try-block. That is why await is designed in such way so it throws only the first exception from a task (or aggregate of tasks) as usually we are interested only in that first exception (we usually handle the first error that occurs).

Null-Conditional Operator in C# 6


C# 6 introduced a Null-Conditional operator which makes null checks more concise. If object on which it is applied is null, it will immediately return null, if not, it will return result of the operation applied on that object (invoking method, property...onto which other operations might be chained). Instead of writing:


var personName = person == null ? null : person.Name;


...we can write:


var personName = person?.Name;


?. is a first form of this operator. The other one is ?[] and is used when accessing array elements. Instead of performing null check of the array and then accessing its elements, we can now put those two operations in a single expression:


var arr = new string[]{"abc" , "def"};
var arr0 = arr?[0]; // "abc"
arr = null;
arr0 = arr?[0]; // null


This operator comes very handy when raising events. Before, we would write:


public event Action SomeEvent;
private void OnSomeEvent()
{
   if (SomeEvent != null)
   {
      SomeEvent.Invoke();
   }
}


...but now we can write:


public event Action SomeEvent;
private void OnSomeEvent()
{
   SomeEvent?.Invoke();
}


Friday 18 December 2015

String interpolation in C# 6

With C# 6 we can finally wave goodbye to the cumbersome, C-style way of injecting values into a string. Before, target string and arguments were separated and indexes were used to place the right argument at the right place inside the string. That was an error prone process.


var id = 123;
var name = "abc";
var s = string.Format("id = {0}, name = {1}", id, name);


New interpolation syntax allows direct injection of variables into the string:


var id = 123;
var name = "abc";
var s = $"id = {id}, name = {name}";


It is possible to inject string result of some more complex expressions:


var task = new Task();
var taskExceptionReport = 
   $"Task.Exception: {((task.Exception == null) ? "null" : task.Exception.ToString())}";



Further reading:
Interpolated Strings (MSDN)
Bill Wagner: "A Pleasant New C# Syntax for String Interpolation"

Sunday 13 December 2015

DO NOT use the same name for class and its namespace

In the following code namespace Foo contains class with the same name - Foo:


This causes compiler to issue an error:

Error CS0118: 'Foo' is a namespace but is used like a type

The problem is in that compiler does not know if we are trying to use new on the namespace or on the actual class. To rectify this, we have to use the fully qualified class name (which includes namespace):


In some cases this might not be enough so it is better to avoid using same name for class and for its namespace.

Eric Lippert has a series of blog articles on this topic:

Do not name a class the same as its namespace


Also, here are some SO Q&A:

'namespace used like a type' error
'CompanyName.Foo' is a 'namespace' but is used like a 'type'

Saturday 12 December 2015

How to set return values for methods returning Task<T>


Non-async method which returns Task<T>


If method is not marked as async and its return type is Task<T>, it has to return object of type Task<T> otherwise compiler issues an error. This is the example of the typical type mismatch error where code:


...causes a compiler error:

Error CS0029: Cannot implicitly convert type 'int' to 'System.Threading.Tasks.Task'

This can be rectified by simply returning expected type:



async method which returns Task<T>


If method is marked as async and its return type is Task<T>, it has to return object of type T, which is int in our case:


...but because async method lacks await in its body, this code generates compiler warning:

Warning CS1998: This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

We can await only methods which return Task or Task<T> so this can be fixed by returning value from awaited completed task:


We have to be careful when calling methods returning Task<T>. If not await-ed, they return Task<T>. If awaited, they return object of Task's generic argument type, T. The following code is not awaiting method returning Task<int>:


...which causes compiler error:

Error CS4016: Since this is an async method, the return expression must be of type 'int' rather than 'Task'

Both methods are awaitable because they return object of type Task:


Asynchronous lambda

If you try to await some task in lambda expression like here:



...you will a compiler error:


Error CS4034: The 'await' operator can only be used within an async lambda expression. Consider marking this lambda expression with the 'async' modifier.


The fix is obvious: apply async to lambda - put it just before lambda's parameter list: