csharp-dotnet-features

C#  .NET features

C# Boxing And Unboxing

Boxing and unboxing are important concepts in C#. The C# Type System contains three data typesValue Types (int, char, etc)Reference Types (object) and Pointer Types. Basically, Boxing converts a Value Type variable into a Reference Type variable, and Unboxing achieves the vice-versa. Boxing and Unboxing enable a unified view of the type system in which a value of any type can be treated as an object.
Boxing In C#

The process of converting a Value Type variable (char, int etc.) to a Reference Type variable (object) is called Boxing.

  • Boxing is an implicit conversion process in which object type (super type) is used.
  • Value Type variables are always stored in Stack memory, while Reference Type variables are stored in Heap memory.
  • Example :
int num = 23; // 23 will assigned to num
Object Obj = num; // Boxing

Description : First, we declare a Value Type variable num of the type int and initialise it with value 23. Now, we create a Reference Type variable obj of the type Object and assign num to it. This assignment implicitly results in the Value Type variable num to be copied and stored in Reference Type variable obj as shown in below figure :

csharp-dotnet-features-1.jpg
Boxing

Let’s understand Boxing with a C# programming code :

// C# implementation to demonstrate
// the Boxing
using System;
class GFG {
// Main Method
static public void Main()
{
// assigned int value
// 2020 to num
int num = 2020;
// boxing
object obj = num;
// value of num to be change
num = 100;
System.Console.WriteLine
("Value - type value of num is : {0}", num);
System.Console.WriteLine
("Object - type value of obj is : {0}", obj);
}
}

Output:

Value - type value of num is : 100
Object - type value of obj is : 2020

As result we see that with change of value type the Reference type is not changed and that is because the boxing should be avoided.

Unboxing In C#
  • The process of converting a Reference Type variable into a Value Type variable is known as Unboxing.
  • It is an explicit conversion process.

Example :

int num = 23;         // value type is int and assigned value 23
Object Obj = num;    // Boxing
int i = (int)Obj;    // Unboxing

Description : We declare a Value Type variable num, which is of the type int and assign it with integer value 23. Now, we create a Reference Type variable obj of the type Object, in which we box the variable num. Now, we create a Value Type integer i to unbox the value from obj. This is done using the casting method, in which we explicitly specify that obj must be cast as an int value. Thus, the Reference Type variable residing in the heap memory is copied to stack as shown in below figure :

csharp-dotnet-features-2.jp
Unboxing

Let’s understand Unboxing with a C# programming code :

// C# implementation to demonstrate
// the Unboxing
using System;
class GFG {
// Main Method
static public void Main()
{
// assigned int value
// 23 to num
int num = 23;
// boxing
object obj = num;
// unboxing
int i = (int)obj;
// Display result
Console.WriteLine("Value of ob object is : " + obj);
Console.WriteLine("Value of i is : " + i);
}
}

Output:

Value of ob object is : 23
Value of i is : 23

In cases such as unboxing of a null object or casting the object as an incompatible data type, the program throws exceptions.

For more info regarding C# and .NET feature look here.

Padding Strings in .NET

Method name Use
String.PadLeft Pads a string with leading characters to a specified total length.
String.PadRight Pads a string with trailing characters to a specified total length.
PadLeft

The String.PadLeft method creates a new string by concatenating enough leading pad characters to an original string to achieve a specified total length. The String.PadLeft(Int32) method uses white space as the padding character and the String.PadLeft(Int32, Char) method enables you to specify your own padding character.

The following code example uses the PadLeft method to create a new string that is twenty characters long. The example displays “--------Hello World!” to the console.

string MyString = "Hello World!";
Console.WriteLine(MyString.PadLeft(20, '-'));
PadRight

The String.PadRight method creates a new string by concatenating enough trailing pad characters to an original string to achieve a specified total length. The String.PadRight(Int32) method uses white space as the padding character and the String.PadRight(Int32, Char) method enables you to specify your own padding character.

The following code example uses the PadRight method to create a new string that is twenty characters long. The example displays “Hello World!--------” to the console.

string MyString = "Hello World!";
Console.WriteLine(MyString.PadRight(20, '-'));

See also: Basic String Operation

Deadlock, Starvation, and Livelock

Prerequisite – Deadlock and Starvation

Livelock occurs when two or more processes continually repeat the same interaction in response to changes in the other processes without doing any useful work. These processes are not in the waiting state, and they are running concurrently. This is different from a deadlock because in a deadlock all processes are in the waiting state.

csharp-dotnet-features-3.png

Example: Imagine a pair of processes using two resources, as shown:

void process_A(void) {     
enter_reg(& resource_1);     
enter_reg(& resource_2);     
use_both_resources();     
leave_reg(& resource_2);     
leave_reg(& resource_1); }
 void process_B(void) {     
enter_reg(& resource_1);    
 enter_reg(& resource_2);    
 use_both_resources();     
leave_reg(& resource_2);     
leave_reg(& resource_1); }

Each of the two processes needs the two resources and they use the polling primitive enter_reg to try to acquire the locks necessary for them. In case, the attempt fails, the process just tries again. If process A runs first and acquires resource 1 and then process B runs and acquires resource 2, no matter which one runs next, it will make no further progress, but neither of the two processes blocks. What actually happens is that it uses its CPU quantum over and over again without any progress being made but also without any sort of blocking. Thus, this situation is not that of a deadlock( as no process is being blocked) but we have something functionally equivalent to a deadlock: LIVELOCK.

What leads to Livelocks?

The occurrence of livelocks can occur in the most surprising ways. The total number of allowed processes in some systems is determined by the number of entries in the process table. Thus process table slots can be referred to as Finite Resources. If a fork fails because of the table being full, waiting a random time and trying again would be a reasonable approach for the program doing the fork. Consider a UNIX system having 100 process slots. Ten programs are running, each of which has to create 12 (sub)processes. After each process has created 9 processes, the 10 original processes and the 90 new processes have exhausted the table. Each of the 10 original processes now sits in an endless loop forking and failing – which is aptly the situation of a deadlock. The probability of this happening is very little but it could happen.

Difference between Deadlock, Starvation, and Livelock:

livelock is similar to a deadlock, except that the states of the processes involved in the livelock constantly change with regard to one another, none progressing. Livelock is a special case of resource starvation; the general definition states that a specific process is not progressing.

Livelock:

var l1 = .... // lock object like semaphore or mutex etc var l2 = .... // lock object like semaphore or mutex etc               // Thread1         
Thread.Start( ()=>
{                   while (true)
{                   
if (!l1.Lock(1000))
 {             
continue;        
 }                   
if (!l2.Lock(1000))
{             
continue;         
}                   
/// do some work     
});         // Thread2         
Thread.Start( ()=>
{                       
while (true)
{                          
 if (!l2.Lock(1000))
 {                 
continue;             
}                           
if (!l1.Lock(1000))
{                 continue;            
 }                           // do some work         
});

Deadlock:

var p = new object();
lock(p)
{
lock(p)
{
// deadlock. Since p is previously locked
// we will never reach here...
}

deadlock is a state in which each member of a group of actions, is waiting for some other member to release a lock. A livelock on the other hand is almost similar to a deadlock, except that the states of the processes involved in a livelock constantly keep on changing with regard to one another, none progressing. Thus Livelock is a special case of resource starvation, as stated from the general definition, the process is not progressing.

Starvation:

Starvation is a problem that is closely related to both, Livelock and Deadlock. In a dynamic system, requests for resources keep on happening. Thereby, some policy is needed to make a decision about who gets the resource and when this process, being reasonable, may lead to some processes never getting serviced even though they are not deadlocked.

Queue q = .....
while (q.Count & gt; 0)
{
var c = q.Dequeue();
.........
// Some method in different thread accidentally
// puts c back in queue twice within same time frame
q.Enqueue(c);
q.Enqueue(c);
// leading to growth of queue twice then it
// can consume, thus starving of computing
}

Starvation happens when “greedy” threads make shared resources unavailable for long periods. For instance, suppose an object provides a synchronized method that often takes a long time to return. If one thread invokes this method frequently, other threads that also need frequent synchronized access to the same object will often be blocked.

Task and Thread

What is Task in C#?
.NET framework provides Threading.Tasks class to let you create tasks and run them asynchronously. A task is an object that represents some work that should be done. The task can tell you if the work is completed and if the operation returns a result, the task gives you the result.
csharp-dotnet-features-5.png

What is Thread?

.NET Framework has thread-associated classes in System.Threading namespace.  A Thread is a small set of executable instructions.
csharp-dotnet-features-6.png
Why we need Tasks
It can be used whenever you want to execute something in parallel. Asynchronous implementation is easy in a task, using’ async’ and ‘await’ keywords.
Why we need a Thread
When the time comes when the application is required to perform few tasks at the same time.
Here is a tutorial on Introduction to Threading in C# 

Differences Between Task And Thread

Here are some differences between a task and a thread.

  1. The Thread class is used for creating and manipulating a thread in Windows. A Task represents some asynchronous operation and is part of the Task Parallel Library, a set of APIs for running tasks asynchronously and in parallel.
  2. The task can return a result. There is no direct mechanism to return the result from a thread.
  3. Task supports cancellation through the use of cancellation tokens. But Thread doesn’t.
  4. A task can have multiple processes happening at the same time. Threads can only have one task running at a time.
  5. We can easily implement Asynchronous using ’async’ and ‘await’ keywords.
  6. A new Thread()is not dealing with Thread pool thread, whereas Task does use thread pool thread.
  7. A Task is a higher level concept than Thread.
Difference between Process and Thread

Process: Processes are basically the programs that are dispatched from the ready state and are scheduled in the CPU for execution. PCB(Process Control Block) holds the concept of process. A process can create other processes which are known as Child Processes. The process takes more time to terminate and it is isolated means it does not share the memory with any other process.

The process can have the following states new, ready, running, waiting, terminated, and suspended.

Thread: Thread is the segment of a process which means a process can have multiple threads and these multiple threads are contained within a process. A thread has three states: Running, Ready, and Blocked.

The thread takes less time to terminate as compared to the process but unlike the process, threads do not isolate.

/csharp-dotnet-features-4.png

 

async, await and Task

The core of async programming is the Task and Task<T> objects, which model asynchronous operations. They are supported by the async and await keywords. The model is fairly simple in most cases: For I/O-bound code, you await an operation that returns a Task or Task<T> inside of an async method.

for more about async programing look  to Async and Await In C#

Task and Result

To get a Result from a Task, you need to create an instance of Task<T> instead of just a pure Task. T represents the type of the result that will be returned. Returning the desired result is identical to other C# methods, so you use the “return” keyword. Finally, to fetch the result, you need to call the Result property. Note that reading this property will wait until its task has completed.

static void Main(string[] args)  
{  
 //creating the task  
Task<int> task1 = new Task<int>(() =>  
 { 
 int result = 1;  
for (int i = 1; i < 10; i++)  
result *= i;  
  return result;  
  });  
//starting the task  
 task1.Start();  
//waiting for result - printing to the console    Console.WriteLine("Task result: {0}", task1.Result); Console.WriteLine("Main method complete. Press any key to finish.");  
 Console.ReadKey();  
}

Await vs Task.Result in an Async Method

await asynchronously unwraps the result of your task, whereas just using Result would block until the task had completed.

Task.Result method that stops the execution flow until the given task has completed

Usingt await:

<span class="hljs-function"><span class="hljs-keyword">async</span> Task<T> <span class="hljs-title">method</span>()</span>{
    <span class="hljs-keyword">var</span> r = <span class="hljs-keyword">await</span> dynamodb.GetItemAsync(...)
    <span class="hljs-keyword">return</span> r.Item;
}

Using Result:

<span class="hljs-function"><span class="hljs-keyword">async</span> Task<T> <span class="hljs-title">method</span>()</span>{
    <span class="hljs-keyword">var</span> task = dynamodb.GetItemAsync(...)
    <span class="hljs-keyword">return</span> task.Result.Item;
}

only the second works. The first one never seems to end.

wait and await

Wait and await – while similar conceptually – are actually completely different. Wait will synchronously block until the task completes. So the current thread is literally blocked waiting for the task to complete. As a general rule, you should use ” async  and await all the way down”; that is, don’t block on async code.

 

This post was part of Topics

Back to home page