• Featured post

C# Task async programming (TAP) and parallel code

The core for asynchronous programming are the objects Task and Task<T>. Both of them are compatible with the keywords async and await.

First of all we need to identify if the code’s I/O-bound or CPU-bound.

  • the code’s limited for external operations and waits for something a lot of time. Examples of this are DDBB calls, or a server’s response. In this case we have to use async/await to free the thread while we wait
  • the code does a CPU-intensive operation. Then we move the work to another thread using Task.Run() so we don’t block the main thread.

async code vs parallel code

(!) Asynchronous code is not the same as parallel code (!)

  • In async code you are trying to make your threads do as little work as possible. This will keep your app responsibe, capable to serve many requests at once and scale well.
  • In parallel code you do the opposite. You use and keep a hold on a thread to do CPU-intensive calculations

async code

The importante of async programming is that you choose when to wait on a task. This way, you can start other tasks concurrently

In async code, one single thread can start the next task concurrently before the previous one completes.
(!) async code doesn’t cause additional threads to be created because an async method doesn’t run on its own thread. (!) It runs on the current synchronization context and uses time on the thread only when the method is active.

parallel code

For parallelism you need multiple threads where each thread executes a task, and all of those tasks are executed at the same time

Read More

C# 12 primary constructors

A concise syntax to declare constructors whose params are available anywhere in the body.

Primary constructors is an easier way to create a constructor for your class or struct, by eliminating the need for explicit declarations of private fields and bodies that only assign param values.

They are great when you just need to do simple initialization of fields and for dependency injection.

Code example using primary constructors

public class Book(int id, string title, IEnumerable<decimal> ratings)
{
	public int Id => id;
	public string Title => title.Trim();
	public int Pages { get; set; }
	public decimal AverageRating => ratings.Any() ? ratings.Average() : 0m;
}

another example

public class Person(string firstName, string lastName)
{
	public string FirstName { get; } = firstName;
	public string LastName { get; } = lastName;
}

Read More

C# 12 collection expressions

Collection expressions try to unify all syntaxes for initializing different collections. With them you can use the same syntax to express collections in a consistent way.

They cannot be used with var. You must declare the type.

// create an array
int[] intArray = [1, 2, 3, 4, 5];
// create empty array
int[] emptyArray = [];
// create a list
List<char> charList = ['D', 'a', 'v', 'i', 'd'];
// create a 2D list
List<int> int2dList = [[1, 2, 3], [4, 5, 6,], [7, 8, 9]];

how to flatten collections

int[] row0 = [1, 2, 3];
int[] row1 = [4, 5, 6];
int[] flattenCollection = [.. row0, 100, .. row1];
foreach(element in flattenCollection)
{
	Console.Write($"{element}, ");
}
// 1, 2, 3, 100, 4, 5, 6,

how to check for list emptiness.

if (item is [])
	Console.WriteLine("list is empty");

if (item is not [])
	Console.WriteLine("list is not empty");

Reference(s)

https://devblogs.microsoft.com/dotnet/refactor-your-code-with-collection-expressions/
https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-12#collection-expressions

C# class vs struct vs record (reference types vs value types)

Reference types vs value types

Reference types are allocated on the heap and garbage-collected, whereas value types are allocated on the stack so their (de)allocation are generally cheaper.

Arrays of reference types contain just references to instances of the reference type residing on the heap. Value type arrays hold the actual instance of the value type. Value type arrays are much cheaper than reference type arrays.

Value types get boxed when cast to a reference type or one of the interfaces they implement. They get unboxed when cast back to the value type. Boxes are objects that are allocated on the heap and are garbage-collected. Too much boxing and unboxing can have a negative impact.
In contrast, no such boxing occurs for reference types.

Reference type assignments copy the reference, whereas value type assignments copy the entire value. Assignments of large reference types are cheaper than assignments of large value types.

Reference types are passed by reference, whereas value types are passed by value. Changes to an instance of a reference type affect all references pointing to the instance. Value type instances are copied when they’re passed. When an instance of a value type is changed, it doesn’t affect any of its copies.

You can’t have a null value type. “null” only means a memory address reference is missing.

Class

Class is a reference type. When you compare reference types, this comparison checks if the compared objects are the same object (heap location).

You can specify access modifier if required (private, public, protected, internal).

class declaration

class Person
{
	public string Name {get; set;}
	public int Age {get; set;}
}

create an object

Person person = new Person();
person.Age = 30;
person.Name = "Mario";
Console.WriteLine(person.Name + " " + person.Age); // Mario 30

create another object using the first object we created

Person person2 = person; 
person2.Age = 29;
Console.WriteLine(person.Name + " " + person.Age); // Mario 29
Console.WriteLine(person2.Name + " " + person2.Age); // Mario 29

Read More

Interact with your pods

This details various ways that you can interact with the code and data running inside your pod.

Access a Pod via Network

If you want access to a specific pod, even if it’s not serving traffic on the internet. To achieve this, Kubernetes has support built into it.

kubectl port-forward <pod-name> <localport>:<podport>
kubectl port-forward istio 5015:80

A secure tunnel is created from your local machine, though the K8s master, to the instance of the Pod running on one of the worker nodes.

Getting More Info with Logs

When you need to debug.

# downloads the current logs from the running instance
kubectl logs kuard

# continuously streams logs
kubectl logs -f kuard

# get logs from a previous instance of the container. Useful if your containers are continuously restarting at startup. 
kubectl logs kuard --previous
  • -c if you have multiple containers in your Pod, you can choose the one to view

Read More

RDF and SPARQL

RDF (Resource Description Framework) - modelo de datos para representar datos como grafos (datos interconectados). Está dirigido y etiquetado para representar la información en la web.

SPARQL - query language estandarizado para consulta de grafos RDF.

Cuando trabajan ambos juntos, RDF y SPARQL te permiten construir aplicaciones de grafos.

What’s an RDF Graph?

This just means data represented using the RDF data model. This is what an example of such graph may look like

rdf-1

An RDF grahp is a directed graph consisting of nodes which are connected together by crearly labelled relationships with directionality. These relationships are known as edges. These edges connect one node to another.

Read More

How to import from JSON to Excel

It’s possible to import directly from JSON to Excel. This allows us to easily filter by some JSON fields or execute Excel queries on top of our JSON data.

I have a json file with hundreds of items following this structure.

{
	"_id": "63371b0027484f4f9f00587d",
	"guid": "ab4059e7-6441-4593-8272-42c53e4742d2",
	"isActive": true,
	"balance": "$2,120.18"
}

Read More

Introduction to GraphQL

What’s GraphQL?

A query language to build & query APIs. Invented by facebook in 2012, to solve its complexity in REST APIs.

It’s a good fit for companies where there’re tons of data we’d need otherwise to access through REST APIs. It’s not a replacement for REST, it’s an alternative for projects with large data sets.

GraphQL vs REST APIs

REST API

underfetching

Let’s say we want to retrieve the posts for a user and then, the comments and likes for a user’s post. In a REST API we’d have the following:

api/users/{id}/posts
api/users/{id}/posts/{postId}/comments
api/users/{id}/posts/{postId}/likes

With a single endpoint we cannot retrieve all the data. We need to call multiple endpoints to have all data we need.

overfetching

Let’s say I want to iterate the PostDescription for one user posts history. If I call the following endpoint it will give to me way more data than I need:

api/users/{id}/posts

gives back:

PostDescription UserId UserImage PostId PostCreationTime PostLocation etc.

This is way more data than I need to iterate and useless to me.

Read More

Windows debug errores

Visor de eventos

Aqui se pueden ver logs de errores y warnings. Interesantes son las carpetas de Registros de Windows - Aplicacion y Sistema windows-debug-1

Administrador de dispositivos

Si hay fallos de red aqui se puede ver el estado de los Adaptadores de Red: windows-debug-2

Dependency injection w. multiple implementations

I have the class package with a type, plus more info not relevant to the question

public class Package
{
	public string Type { get; set; }
	// ... more package properties
}

I have the following interface service to mail packages

public interface IMailService
{
	public Task<string> SendPackage(Package package);
}

Then I have several implementations for this interface

public class MailNewPackageService : IMailService
{
	public async Task<string> SendPackage(Package package)
	{
		Console.WriteLine("send package through new service");
		// implementation ...
	}
}

public class MailOldPackageService : IMailService
{
	public async Task<string> SendPackage(Package package)
	{
		Console.WriteLine("send package through old service");
		// implementation ...
	}
}

Read More

C# Events (pub/sub)

Permite a una clase notificar a otras cuando ocurre algo de interés.

public class Publicador
{
	// Declaracion de un evento
	public event EventHandler EventoSimple;

	// trigger
	public void DispararEvento()
	{
		// verificacion de subscripcion
		if(EventoSimple != null)
		{
			EventoSimple(this, EventArgs.Empty);
		}
	}
}
public class Suscriptor
{
	public void Suscribirse(Publicador publicador)
	{
		// suscripcion al evento
		publicador.EventoSimple += ManejadorEvento;
	}

	private void ManejadorEvento(object sender, EventArgs e)
	{
		// do whatever you need to do and/or send here
	}
}
// usage
var publicador = new Publicador();
var suscriptor = new Suscriptor();
suscriptor.Suscribirse(publicador);