Other
Other
C# FileStream class provides a stream for file operation. It can be used to perform
synchronous and asynchronous read and write operations. By the help of
FileStream class, we can easily read and write data into file.
Let's see the simple example of FileStream class to write single byte of data into file.
Here, we are using OpenOrCreate file mode which can be used for read and write
operations.
using System;
using System.IO;
public class FileStreamExample
{
public static void Main(string[] args)
{
FileStream f = new FileStream("e:\\b.txt", FileMode.OpenOrCreate);//creating file
f.WriteByte(65); //writing byte into stream
f.Close(); //closing stream
}
} output: A
Let's see the example of FileStream class to read data from the file. Here, ReadByte()
method of FileStream class returns single byte. To all read all the bytes, you need to use
loop.
using System;
using System.IO;
public class FileStreamExample
{
public static void Main(string[] args)
{
FileStream f = new FileStream("e:\\b.txt", FileMode.OpenOrCreate);
int i = 0;
while ((i = f.ReadByte()) != -1)
{
Console.Write((char)i);
}
f.Close();
}
}
Output: ABCDEFGHIJKLMNOPQRSTUVWXYZ
C# StreamWriter
using System;
using System.IO;
public class StreamWriterExample
{
public static void Main(string[] args)
{
FileStream f = new FileStream("e:\\output.txt", FileMode.Create);
StreamWriter s = new StreamWriter(f);
s.WriteLine("hello c#");
s.Close();
f.Close();
Console.WriteLine("File created successfully...");
}
}
Now open the file, you will see the text "hello c#" in output.txt file.
Output.txt: hello c#
C# StreamReader
using System;
using System.IO;
public class StreamReaderExample
{
public static void Main(string[] args)
{
FileStream f = new FileStream("e:\\output.txt", FileMode.OpenOrCreate);
StreamReader s = new StreamReader(f);
string line=s.ReadLine();
Console.WriteLine(line);
s.Close();
f.Close();
}
} Output: Hello C#
using System;
using System.IO;
public class StreamReaderExample
{
public static void Main(string[] args)
{
FileStream f = new FileStream("e:\\a.txt", FileMode.OpenOrCreate);
StreamReader s = new StreamReader(f);
string line = "";
while ((line = s.ReadLine()) != null)
{
Console.WriteLine(line);
}
s.Close();
f.Close();
} output: Hello C#
} this is file handling
C# TextWriter
using System;
using System.IO;
namespace TextWriterExample
{
class Program
{
static void Main(string[] args)
{
using (TextWriter writer = File.CreateText("e:\\f.txt"))
{
writer.WriteLine("Hello C#");
writer.WriteLine("C# File Handling by JavaTpoint");
}
Console.WriteLine("Data written successfully...");
}
}
} Output: Data written successfully...
C# TextReader
Let's see the simple example of TextReader class that reads data till the end of file.
using System;
using System.IO;
namespace TextReaderExample
{
class Program
{
static void Main(string[] args)
{
using (TextReader tr = File.OpenText("e:\\f.txt"))
{
Console.WriteLine(tr.ReadToEnd());
}
}
}
} Output: Hello C#
C# File Handling by JavaTpoint
C# BinaryWriter
using System;
using System.IO;
namespace BinaryWriterExample
{
class Program
{
static void Main(string[] args)
{
string fileName = "e:\\binaryfile.dat";
using (BinaryWriter writer = new BinaryWriter(File.Open(ilename, FileMode.Create)))
{
writer.Write(2.5);
writer.Write(“this is string data”);
writer.Write(true);
}
Console.WriteLine(“Data written successfully…”);
}
}
}
Output:
using System;
using System.IO;
namespace BinaryWriterExample
{
class Program
{
static void Main(string[] args)
{
WriteBinaryFile();
ReadBinaryFile();
Console.ReadKey();
}
static void WriteBinaryFile()
{
using (BinaryWriter writer = new BinaryWriter(File.Open("e:\\binaryfile.dat", FileMode.Create)))
{
writer.Write(12.5);
writer.Write("this is string data");
writer.Write(true);
}
}
static void ReadBinaryFile()
{
using (BinaryReader reader = new BinaryReader(File.Open("e:\\binaryfile.dat", FileMode.Open)))
{
Console.WriteLine("Double Value : " + reader.ReadDouble());
Console.WriteLine("String Value : " + reader.ReadString());
Console.WriteLine("Boolean Value : " + reader.ReadBoolean());
}
}
}
} Output:
Double Value : 12.5
String Value : this is string data
Boolean Value : true
C# StringWriter Class
This class is used to write and deal with string data rather than files. It is derived
class of TextWriter class. The string data written by StringWriter class is stored
into StringBuilder.
The purpose of this class is to manipulate string and save result into the
StringBuilder.
[SerializableAttribute]
[ComVisibleAttribute(true)]
public class StringWriter : TextWriter
C# StringWriter Example
using System;
using System.IO;
using System.Text;
namespace CSharpProgram
{
class Program
{
static void Main(string[] args)
{
string text = "Hello, Welcome to the javatpoint \n" +
"It is nice site. \n" +
"It provides technical tutorials";
// Creating StringBuilder instance
StringBuilder sb = new StringBuilder();
C# StringReader Signature
[SerializableAttribute]
[ComVisibleAttribute(true)]
public class StringReader : TextReader
using System;
using System.IO;
namespace CSharpProgram
{
class Program
{
static void Main(string[] args)
{
StringWriter str = new StringWriter();
str.WriteLine("Hello, this message is read by StringReader class");
str.Close();
// Creating StringReader instance and passing StringWriter
StringReader reader = new StringReader(str.ToString());
// Reading data
while (reader.Peek() > -1)
{
Console.WriteLine(reader.ReadLine());
}
}
}
}
Output: Hello, this message is read by StringReader class
C# FileInfo Class
The FileInfo class is used to deal with file and its operations in C#. It provides
properties and methods that are used to create, delete and read file. It uses
StreamWriter class to write data to the file. It is a part of System.IO namespace.
[SerializableAttribute]
[ComVisibleAttribute(true)]
public sealed class FileInfo : FileSystemInfo
C# FileInfo Example: Creating a File
using System;
using System.IO;
namespace CSharpProgram
{
class Program
{
static void Main(string[] args)
{
try
{
// Specifying file location
string loc = "F:\\abc.txt";
// Creating FileInfo instance
FileInfo file = new FileInfo(loc);
// Creating an empty file
file.Create();
Console.WriteLine("File is created Successfuly");
}catch(IOException e)
{
Console.WriteLine("Something went wrong: "+e);
}
}
}
} Output: File is created Successfully
using System;
using System.IO;
namespace CSharpProgram
{
class Program
{
static void Main(string[] args)
{
try
{
// Specifying file location
string loc = "F:\\abc.txt";
// Creating FileInfo instance
FileInfo file = new FileInfo(loc);
// Creating an file instance to write
StreamWriter sw = file.CreateText();
// Writing to the file
sw.WriteLine("This text is written to the file by using StreamWriter class.");
sw.Close();
}
catch(IOException e)
{
Console.WriteLine("Something went wrong: "+e);
}
}
}
}
using System;
using System.IO;
namespace CSharpProgram
{
class Program
{
static void Main(string[] args)
{
try
{
// Specifying file to read
string loc = "F:\\abc.txt";
// Creating FileInfo instance
FileInfo file = new FileInfo(loc);
// Opening file to read
StreamReader sr = file.OpenText();
string data = "";
while ((data = sr.ReadLine()) != null)
{
Console.WriteLine(data);
}
}
catch (IOException e)
{
Console.WriteLine("Something went wrong: " + e);
}
}
}
}
C# DirectoryInfo Class
C# DirectoryInfo Syntax
[SerializableAttribute]
[ComVisibleAttribute(true)]
public sealed class DirectoryInfo : FileSystemInfo
using System;
using System.IO;
namespace CSharpProgram
{
class Program
{
static void Main(string[] args)
{
// Provide directory name with complete location.
DirectoryInfo directory = new DirectoryInfo(@"F:\javatpoint");
try
{
// Check, directory exist or not.
if (directory.Exists)
{
Console.WriteLine("Directory already exist.");
return;
}
// Creating a new directory.
directory.Create();
Console.WriteLine("The directory is created successfully.");
}
catch (Exception e)
{
Console.WriteLine("Directory not created: {0}", e.ToString());
}
}
}
} Output: The directory is created successfully.
C# Serialization
serialization is the process of converting object into byte stream so that it can be
saved to memory, file or database. The reverse process of serialization is called
deserialization.
C# SerializableAttribute
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
[Serializable]
class Student
{
int rollno;
string name;
public Student(int rollno, string name)
{
this.rollno = rollno;
this.name = name;
}
}
public class SerializeExample
{
public static void Main(string[] args)
{
FileStream stream = new FileStream("e:\\sss.txt", FileMode.OpenOrCreate);
BinaryFormatter formatter=new BinaryFormatter();
stream.Close();
}
}
C# Deserialization
deserialization is the reverse process of serialization. It means you can read the
object from byte stream. Here, we are going to
use BinaryFormatter.Deserialize(stream) method to deserialize the stream.
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
[Serializable]
class Student
{
public int rollno;
public string name;
public Student(int rollno, string name)
{
this.rollno = rollno;
this.name = name;
}
}
public class DeserializeExample
{
public static void Main(string[] args)
{
FileStream stream = new FileStream("e:\\sss.txt", FileMode.OpenOrCreate);
BinaryFormatter formatter=new BinaryFormatter();
Student s=(Student)formatter.Deserialize(stream);
Console.WriteLine("Rollno: " + s.rollno);
Console.WriteLine("Name: " + s.name);
stream.Close();
}
}
Output:
Rollno: 101
Name: sonoo
C# System.IO Namespace
store object
update object
delete object
retrieve object
search object, and
sort object
We can store objects in array or collection. Collection has advantage over array.
Array has size limit but objects stored in collection can grow or shrink
dynamically.
Types of Collections in C#
System.Collections.Generic classes
System.Collections classes (Now deprecated)
System.Collections.Concurrent classesAD
1) System.Collections.Generic classes
List
Stack
Queue
LinkedList
HashSet
SortedSet
Dictionary
SortedDictionary
SortedList
2) System.Collections classes
ArrayList
Stack
Queue
Hashtable
3) System.Collections.Concurrent classes
BlockingCollection
ConcurrentBag
ConcurrentStack
ConcurrentQueue
ConcurrentDictionary
Partitioner
Partitioner
OrderablePartitioner
C# List<T>
C# List<T> class is used to store and fetch elements. It can have duplicate
elements. It is found in System.Collections.Generic namespace.
using System;
using System.Collections.Generic;
public class ListExample
{
public static void Main(string[] args)
{
// Create a list of strings
var names = new List<string>();
names.Add("Sonoo Jaiswal");
names.Add("Ankit");
names.Add("Peter");
names.Add("Irfan");
// Iterate list element using foreach loop
foreach (var name in names)
{
Console.WriteLine(name);
}
}
}
Output:
Sonoo Jaiswal
Ankit
Peter
Irfan
C# HashSet<T>
C# HashSet class can be used to store, remove or view elements. It does not store
duplicate elements.
It is suggested to use HashSet class if you have to store only unique elements. It
is found in System.Collections.Generic namespace.
using System;
using System.Collections.Generic;
public class HashSetExample
{
public static void Main(string[] args)
{
// Create a set of strings
var names = new HashSet<string>();
names.Add("Sonoo");
names.Add("Ankit");
names.Add("Peter");
names.Add("Irfan");
names.Add("Ankit"); //will not be added
Ankit
Peter
Irfan
C# SortedSet<T>
It is suggested to use SortedSet class if you have to store unique elements and
maintain ascending order. It is found in System.Collections.Generic namespace.
using System;
using System.Collections.Generic;
public class SortedSetExample
{
public static void Main(string[] args)
{
// Create a set of strings
var names = new SortedSet<string>();
names.Add("Sonoo");
names.Add("Ankit");
names.Add("Peter");
names.Add("Irfan");
names.Add("Ankit"); //will not be added
Output:
Ankit
Irfan
Peter
Sonoo
C# Stack<T>
C# Stack<T> class is used to push and pop elements. It uses the concept of Stack
that arranges elements in LIFO (Last In First Out) order. It can have duplicate
elements. It is found in System.Collections.Generic namespace.
Let's see an example of generic Stack<T> class that stores elements using Push()
method, removes elements using Pop() method and iterates elements using for-
each loop.
using System;
using System.Collections.Generic;
public class StackExample
{
public static void Main(string[] args)
{
Stack<string> names = new Stack<string>();
names.Push("Sonoo");
names.Push("Peter");
names.Push("James");
names.Push("Ratan");
names.Push("Irfan");
Sonoo
Peter
James
Ratan
Irfan
Peek element: Irfan
Pop: Irfan
After Pop, Peek element: Ratan
C# Queue<T>
C# Queue<T> class is used to Enqueue and Dequeue elements. It uses the
concept of Queue that arranges elements in FIFO (First In First Out) order. It can
have duplicate elements. It is found in System.Collections.Generic namespace.
example of generic Queue<T> class that stores elements using Enqueue()
method, removes elements using Dequeue() method and iterates elements using
for-each loop.
using System;
using System.Collections.Generic;
public class QueueExample
{
public static void Main(string[] args)
{
Queue<string> names = new Queue<string>();
names.Enqueue("Sonoo");
names.Enqueue("Peter");
names.Enqueue("James");
names.Enqueue("Ratan");
names.Enqueue("Irfan");
C# LinkedList<T>
C# LinkedList<T> class uses the concept of linked list. It allows us to insert and
delete elements fastly. It can have duplicate elements. It is found in
System.Collections.Generic namespace.
It allows us to add and remove element at before or last index.
Let's see an example of generic LinkedList<T> class that stores elements using
AddLast() and AddFirst() methods and iterates elements using for-each loop.
using System;
using System.Collections.Generic;
Output:
John
Sonoo Jaiswal
Ankit
Peter
Irfan
C# Dictionary<TKey, TValue>
C# Dictionary<TKey, TValue> class uses the concept of hashtable. It stores values
on the basis of key. It contains unique keys only. By the help of key, we can easily
search or remove elements. It is found in System.Collections.Generic namespace.
Let's see an example of generic Dictionary<TKey, TValue> class that stores
elements using Add() method and iterates elements using for-each loop. Here,
we are using KeyValuePair class to get key and value.
using System;
using System.Collections.Generic;
Output:
1 Sonoo
2 Peter
3 James
4 Ratan
5 Irfan
C# SortedDictionary<TKey, TValue>
C# SortedDictionary<TKey, TValue> class uses the concept of hashtable. It stores
values on the basis of key. It contains unique keys and maintains ascending order
on the basis of key. By the help of key, we can easily search or remove elements.
It is found in System.Collections.Generic namespace.
example of generic SortedDictionary<TKey, TValue> class that stores elements
using Add() method and iterates elements using for-each loop. Here, we are
using KeyValuePair class to get key and value.
using System;
using System.Collections.Generic;
Output:
1 Sonoo
2 Irfan
3 Ratan
4 Peter
5 James
C# SortedList<TKey, TValue>
C# SortedList<TKey, TValue> is an array of key/value pairs. It stores values on the
basis of key. The SortedList<TKey, TValue> class contains unique keys and
maintains ascending order on the basis of key. By the help of key, we can easily
search or remove elements. It is found in System.Collections.Generic namespace.
It is like SortedDictionary<TKey, TValue> class.
SortedList<TKey, TValue> class uses less memory than SortedDictionary<TKey,
TValue>. It is recommended to use SortedList<TKey, TValue> if you have to store
and retrieve key/valye pairs. The SortedDictionary<TKey, TValue> class is faster
than SortedList<TKey, TValue> class if you perform insertion and removal for
unsorted data.
using System;
using System.Collections.Generic;
Output:
1 Sonoo
2 Irfan
3 Ratan
4 Peter
5 James
C# Generics
Generic is a concept that allows us to define classes and methods with
placeholder. C# compiler replaces these placeholders with specified type at
compile time. The concept of generics is used to create general purpose classes
and methods.
define generic class, we must use angle <> brackets. The angle brackets are used
to declare a class or method as generic type. In the following example, we are
creating generic class that can be used to deal with any type of data.
using System;
namespace CSharpProgram
{
class GenericClass<T>
{
public GenericClass(T msg)
{
Console.WriteLine(msg);
}
}
class Program
{
static void Main(string[] args)
{
GenericClass<string> gen = new GenericClass<string> ("This is generic
class");
GenericClass<int> genI = new GenericClass<int>(101);
GenericClass<char> getCh = new GenericClass<char>('I');
}
}
}
Output:
C# Delegates
In C#, delegate is a reference to the method. It works like function pointer in C and
C++. But it is objected-oriented, secured and type-safe than function pointer.
For static method, delegate encapsulates method only. But for instance method,
it encapsulates method and instance both.
The best use of delegate is to use as event.
Let's see a simple example of delegate in C# which calls add() and mul() methods.
using System;
delegate int Calculator(int n); //declaring delegate
public class DelegateExample
{
static int number = 100;
public static int add(int n)
{
number = number + n;
return number;
}
public static int mul(int n)
{
number = number * n;
return number;
}
public static int getNumber()
{
return number;
}
public static void Main(string[] args)
{
Calculator c1 = new Calculator(add);//instantiating delegate
Calculator c2 = new Calculator(mul);
c1(20);//calling method using delegate
Console.WriteLine("After c1 delegate, Number is: " + getNumber());
c2(3);
Console.WriteLine("After c2 delegate, Number is: " + getNumber());
}
} After c1 delegate, Number is: 120
After c2 delegate, Number is: 360
C# Reflection
reflection is a process to get metadata of a type at runtime. The System.Reflection
namespace contains required classes for reflection such as:
Type
MemberInfo
ConstructorInfo
MethodInfo
FieldInfo
PropertyInfo
TypeInfo
EventInfo
Module
Assembly
AssemblyName
Pointer etc.
C# Type class
C# Type class represents type declarations for class types, interface types,
enumeration types, array types, value types etc. It is found in System namespace.
It inherits System.Reflection.MemberInfo class.
C# Reflection Example: Get Type
using System;
public class ReflectionExample
{
public static void Main()
{
int a = 10;
Type type = a.GetType();
Console.WriteLine(type);
}
} output: System.Int32
C# Reflection Example: Get Assembly
using System;
using System.Reflection;
public class ReflectionExample
{
public static void Main()
{
Type t = typeof(System.String);
Console.WriteLine(t.Assembly);
}
} Output: mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Output:
System.String
System.Object
true
false
false
C# Anonymous Functions
Anonymous function is a type of function that does not has name. In other
words, we can say that a function without name is known as anonymous function.
Lambda Expressions
Anonymous Methods
C# Lambda Expressions
using System;
namespace LambdaExpressions
{
class Program
{
delegate int Square(int num);
static void Main(string[] args)
{
Square GetSquare = x => x * x;
int j = GetSquare(5);
Console.WriteLine("Square: "+j);
}
}
}
Output:
Square: 25
C# Anonymous Methods
using System;
namespace AnonymousMethods
{
class Program
{
public delegate void AnonymousFun();
static void Main(string[] args)
{
AnonymousFun fun = delegate ()
{
Console.WriteLine("This is anonymous function");
};
fun();
}
}
} Output: This is anonymous function
C# Multithreading
System.Threading Namespace
Thread
Mutex
Timer
Monitor
Semaphore
ThreadLocal
ThreadPool
Volatile etc.
In C#, each thread has a life cycle. The life cycle of a thread is started when
instance of System.Threading.Thread class is created. When the task execution of
the thread is completed, its life cycle is ended.
Unstarted
Runnable (Ready to run)
Running
Not Runnable
Dead (Terminated)
Unstarted State
Runnable State
Running State
Only one thread within a process can be executed at a time. At the time of
execution, thread is in running state.
The thread is in not runnable state, if sleep() or wait() method is called on the
thread, or input/output operation is blocked.
Dead State
After completing the task, thread enters into dead or terminated state.
C# Thread class
C# Thread class provides properties and methods to create and control threads. It
is found in System.Threading namespace.
The first thread which is created inside a process is called Main thread. It starts first and ends at last.
using System;
using System.Threading;
public class ThreadExample
{
public static void Main(string[] args)
{
Thread t = Thread.CurrentThread;
t.Name = "MainThread";
Console.WriteLine(t.Name);
}
} Output: MainThread
1. using System;
2. using System.Threading;
3. public class MyThread
4. {
5. public static void Thread1()
6. {
7. for (int i = 0; i < 10; i++)
8. {
9. Console.WriteLine(i);
10. }
11. }
12. }
13. public class ThreadExample
14. {
15. public static void Main()
16. {
17. Thread t1 = new Thread(new ThreadStart(MyThread.Thread1));
18. Thread t2 = new Thread(new ThreadStart(MyThread.Thread1));
19. t1.Start();
20. t2.Start();
21. }
22. }
Output: 0 1 2 3 4 5 0 1 2 3 4 5 6 7 8 9
The output of the above program can be anything because there is context switching
between the threads.
For non-static method, you need to create instance of the class so that you can refer it
in the constructor of ThreadStart class.
using System;
using System.Threading;
public class MyThread
{
public void Thread1()
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine(i);
}
}
}
public class ThreadExample
{
public static void Main()
{
MyThread mt = new MyThread();
Thread t1 = new Thread(new ThreadStart(mt.Thread1));
Thread t2 = new Thread(new ThreadStart(mt.Thread1));
t1.Start();
t2.Start();
}
}
Output: 0 1 2 3 4 5 0 1 2 3 4 5 6 7 8 9
Like above program output, the output of this program can be anything because there
is context switching between the threads.
using System;
using System.Threading;
public class MyThread
{
public void Thread1()
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine(i);
Thread.Sleep(200);
}
}
}
public class ThreadExample
{
public static void Main()
{
MyThread mt = new MyThread();
Thread t1 = new Thread(new ThreadStart(mt.Thread1));
Thread t2 = new Thread(new ThreadStart(mt.Thread1));
t1.Start();
t2.Start();
}
} Output: 0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9
using System;
using System.Threading;
public class MyThread
{
public void Thread1()
{
for (int i = 0; i < 5; i++)
{
Console.WriteLine(i);
Thread.Sleep(200);
}
}
}
public class ThreadExample
{
public static void Main()
{
MyThread mt = new MyThread();
Thread t1 = new Thread(new ThreadStart(mt.Thread1));
Thread t2 = new Thread(new ThreadStart(mt.Thread1));
Thread t3 = new Thread(new ThreadStart(mt.Thread1));
t1.Start();
t1.Join();
t2.Start();
t3.Start();
}
}
Output: 0 1 2 3 4 0 0 1 1 2 2 3 3 4 4
using System;
using System.Threading;
public class MyThread
{
public void Thread1()
{
Thread t = Thread.CurrentThread;
Console.WriteLine(t.Name+" is running");
}
}
public class ThreadExample
{
public static void Main()
{
MyThread mt = new MyThread();
Thread t1 = new Thread(new ThreadStart(mt.Thread1));
Thread t2 = new Thread(new ThreadStart(mt.Thread1));
Thread t3 = new Thread(new ThreadStart(mt.Thread1));
t1.Name = "Player1";
t2.Name = "Player2";
t3.Name = "Player3";
t1.Start();
t2.Start();
t3.Start();
}
}
Output:
Player1 is running
Player2 is running
Player3 is running
using System;
using System.Threading;
public class MyThread
{
public void Thread1()
{
Thread t = Thread.CurrentThread;
Console.WriteLine(t.Name+" is running");
}
}
public class ThreadExample
{
public static void Main()
{
MyThread mt = new MyThread();
Thread t1 = new Thread(new ThreadStart(mt.Thread1));
Thread t2 = new Thread(new ThreadStart(mt.Thread1));
Thread t3 = new Thread(new ThreadStart(mt.Thread1));
t1.Name = "Player1";
t2.Name = "Player2";
t3.Name = "Player3";
t3.Priority = ThreadPriority.Highest;
t2.Priority = ThreadPriority.Normal;
t1.Priority = ThreadPriority.Lowest;
t1.Start();
t2.Start();
t3.Start();
}
} Output: Player1 is running
Player3 is running
Player2 is running
The output is unpredictable because threads are highly system dependent. It may
follow any algorithm preemptive or non-preemptive.
C# Thread Synchronization
Synchronization is a technique that allows only one thread to access the resource
for the particular time. No other thread can interrupt until the assigned thread
finishes its task.
In multithreading program, threads are allowed to access any resource for the
required execution time. Threads share resources and executes asynchronously.
Accessing shared resources (data) is critical task that sometimes may halt the
system. We deal with it by making threads synchronized.
C# Lock
In this example, we are not using lock. This example executes asynchronously. In
other words, there is context-switching between the threads.
using System;
using System.Threading;
class Printer
{
public void PrintTable()
{
for (int i = 1; i <= 10; i++)
{
Thread.Sleep(100);
Console.WriteLine(i);
}
}
}
class Program
{
public static void Main(string[] args)
{
Printer p = new Printer();
Thread t1 = new Thread(new ThreadStart(p.PrintTable));
Thread t2 = new Thread(new ThreadStart(p.PrintTable));
t1.Start();
t2.Start();
}
}
Output: 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10
In this example, we are using lock. This example executes synchronously. In other
words, there is no context-switching between the threads. In the output section,
we can see that second thread starts working after first threads finishes its tasks.
using System;
using System.Threading;
class Printer
{
public void PrintTable()
{
lock (this)
{
for (int i = 1; i <= 10; i++)
{
Thread.Sleep(100);
Console.WriteLine(i);
}
}
}
}
class Program
{
public static void Main(string[] args)
{
Printer p = new Printer();
Thread t1 = new Thread(new ThreadStart(p.PrintTable));
Thread t2 = new Thread(new ThreadStart(p.PrintTable));
t1.Start();
t2.Start();
}
}
Output: 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10