Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

3RD Unit

Download as pdf or txt
Download as pdf or txt
You are on page 1of 6

1.

Assemblies in C#
An Assembly is a compiled code library used by .NET applications. Assemblies are the basic
units of deployment, version control, reuse, activation scoping, and security permissions. In
.NET, an application consists of one or more assemblies. Assemblies can be either executable
(.exe) files or library (.dll) files.
Components of an Assembly:
1. Manifest: Contains metadata about the assembly, including version information,
culture, and strong name. It also specifies the types exposed by the assembly and the
assembly's dependencies on other assemblies.
2. Metadata: Describes the data about the assembly's types (classes, structs, interfaces,
enums, etc.), methods, and properties.
3. IL Code: Contains the Intermediate Language (IL) code, which is CPU-independent
code that will be converted to machine code at runtime by the .NET Just-In-Time
(JIT) compiler.
4. Resources: These can include images, strings, and other non-executable data required
by the application.
Types of Assemblies:
 Private Assemblies: These assemblies are used by a single application and are
located in the application's folder or subfolder. They cannot be shared across multiple
applications.
 Shared Assemblies: These are designed to be used by multiple applications and are
stored in the Global Assembly Cache (GAC).
Global Assembly Cache (GAC):
The GAC is a machine-wide repository used to store assemblies that are shared by multiple
applications. Assemblies in the GAC must have a strong name, which ensures uniqueness
across machines. Strong names consist of:
 Assembly Name
 Version Number
 Culture Information
 Public/Private Key Pair
Assemblies placed in the GAC can be accessed by any application on the machine, ensuring
centralized management of shared libraries.
Strong Naming and Versioning:
Assemblies can be given a strong name to ensure uniqueness across multiple machines. A
strong-named assembly is protected from being tampered with, as it includes a cryptographic
key signature. Strong naming is required for assemblies placed in the GAC.
Versioning allows multiple versions of the same assembly to coexist. This ensures backward
compatibility, as applications can target a specific version of an assembly, preventing version
conflicts.
Creating and Loading Assemblies:
Assemblies are created during the compilation process of .NET applications. The csc.exe
compiler, or Visual Studio’s build process, compiles C# code into an assembly (either .exe or
.dll).
You can load assemblies dynamically at runtime using Assembly.Load() or
Assembly.LoadFrom() methods. This is useful for scenarios like plugins or dynamically
loading components.
csharp
Copy code
Assembly myAssembly = Assembly.LoadFrom("MyAssembly.dll");
2. Threads in C#
A thread is the smallest unit of execution in a .NET process. In a multithreaded environment,
multiple threads run concurrently to perform tasks in parallel, enhancing application
performance, especially in I/O-bound or CPU-bound tasks.
Thread Lifecycle:
 Unstarted: The thread is created but not yet started.
 Running: The thread is executing.
 Blocked/Waiting: The thread is paused, usually waiting for a resource or event.
 Stopped: The thread has completed execution or has been terminated.
Thread Creation:
In C#, threads are created using the Thread class from the System.Threading namespace. A
new thread is started using the Thread.Start() method.
csharp
Copy code
Thread t = new Thread(new ThreadStart(MyMethod));
t.Start();
You can pass data to a thread using the ParameterizedThreadStart delegate.
csharp
Copy code
Thread t = new Thread(new ParameterizedThreadStart(MyMethod));
t.Start(data);
Foreground and Background Threads:
 Foreground threads continue to execute until they complete, even if the main
application thread has finished. By default, threads are foreground threads.
 Background threads, on the other hand, are terminated when all foreground threads
in a process have completed.
You can set a thread as a background thread using:
csharp
Copy code
Thread t = new Thread(MyMethod);
t.IsBackground = true;
t.Start();
Thread Safety:
Access to shared data across multiple threads can lead to race conditions. To ensure thread
safety, synchronization techniques must be used to prevent multiple threads from
simultaneously accessing shared resources.
3. AppDomains (Application Domains)
Application Domains (AppDomains) are an important part of the .NET runtime, providing
isolation between executing applications or components within the same process. They are a
lightweight alternative to processes for providing isolation, unloading, and security
boundaries.
Key Benefits:
1. Isolation: Each AppDomain is a separate environment. Code running in one
AppDomain cannot interfere with code running in another AppDomain.
2. Security: AppDomains provide an isolation boundary for security. This is useful in
scenarios like running plugins or dynamically loading code.
3. Unloading: Unlike processes, AppDomains can be unloaded without shutting down
the entire process. This is useful for cleaning up resources or reloading code.
Creating and Unloading AppDomains:
You can create a new AppDomain using the AppDomain.CreateDomain() method, and unload
it using AppDomain.Unload().
csharp
Copy code
AppDomain newDomain = AppDomain.CreateDomain("NewAppDomain");
AppDomain.Unload(newDomain);
Communication between AppDomains can occur through remoting or marshaling of
objects.
4. Processes
A process is an instance of a running application. It has its own memory space and system
resources. Each process can contain multiple threads, and the operating system handles
scheduling of these threads across the CPU cores.
Process Class:
In C#, the System.Diagnostics.Process class allows you to create, manage, and monitor
processes. You can start new processes, kill them, or check their status.
csharp
Copy code
Process process = new Process();
process.StartInfo.FileName = "notepad.exe";
process.Start();
5. Concurrency and Synchronization
Concurrency refers to the ability to run multiple tasks simultaneously. Synchronization
ensures that shared resources are accessed safely in a multithreaded environment.
Common Synchronization Techniques:
1. Locks (lock keyword): A lock ensures that only one thread can access a particular
block of code at a time. It prevents race conditions by locking a shared resource
during critical code execution.
csharp
Copy code
lock (lockObject) {
// Critical section code
}
The lockObject is an object used to enforce locking. When a thread holds the lock, other
threads must wait until the lock is released.
2. Monitors: The Monitor class provides similar functionality to lock but gives finer
control. You can explicitly call Monitor.Enter() and Monitor.Exit() to begin and end
critical sections.
csharp
Copy code
Monitor.Enter(lockObject);
try {
// Critical section
}
finally {
Monitor.Exit(lockObject);
}
Additionally, Monitor.Wait() and Monitor.Pulse() methods can implement advanced
synchronization techniques, like the producer-consumer problem.
3. ReaderWriterLock: The ReaderWriterLock allows multiple threads to read
concurrently while allowing only one thread to write. This is useful for scenarios
where reads are more frequent than writes.
csharp
Copy code
ReaderWriterLock rwLock = new ReaderWriterLock();
rwLock.AcquireReaderLock(Timeout.Infinite);
// Perform read operations
rwLock.ReleaseReaderLock();
4. Mutex: A Mutex is a synchronization primitive that can be used across processes,
unlike locks that are limited to threads within the same process. A Mutex ensures that
only one thread or process can access a resource at a time.
csharp
Copy code
Mutex mutex = new Mutex();
mutex.WaitOne(); // Acquires the lock
// Perform critical operations
mutex.ReleaseMutex(); // Releases the lock
5. Semaphore: A Semaphore restricts access to a resource by a limited number of
threads. It allows a certain number of threads to access a resource simultaneously, but
blocks further access when the limit is reached.
csharp
Copy code
Semaphore semaphore = new Semaphore(2, 2); // Max 2 threads
semaphore.WaitOne(); // Acquire access
// Perform operations
semaphore.Release(); // Release access
6. Thread Pooling: The ThreadPool class allows you to reuse a pool of worker threads
for short tasks, avoiding the overhead of creating and destroying threads. You can
queue tasks to the thread pool using ThreadPool.QueueUserWorkItem.
csharp
Copy code
ThreadPool.QueueUserWorkItem(state => {
// Task code here
});
7. Tasks and the Task Parallel Library (TPL): The Task class in the
System.Threading.Tasks namespace provides a higher-level abstraction for
multithreading, allowing easier handling of parallel execution. The Task Parallel
Library (TPL) manages the efficient execution of tasks.
csharp
Copy code
Task t = Task.Run(() => MyMethod());
t.Wait(); // Waits for the task to complete

You might also like