1. What do you know about .NET assemblies? Assemblies are the smallest units of versioning and deployment in the .NET application. Assemblies are also the building blocks for programs such as Web services, Windows services, serviced components, and .NET remoting applications.
2. What’s the difference between private and shared assembly?
Private assembly is used inside an application only and does not have to be identified by a strong name. Shared assembly can be used by multiple applications and has to have a strong name.
3. What’s a strong name? A strong name includes the name of the assembly, version number, culture identity, and a public key token.
4. How can you tell the application to look for assemblies at the locations other than its own install? Use the
directive in the XML .config file for a given application.
should do the trick. Or you can add additional search paths in the
Properties box of the deployed application.
5. How can you debug failed assembly binds? Use the Assembly
Binding Log Viewer (fuslogvw.exe) to find out the paths searched.
6. Where are shared assemblies stored? Global assembly cache.
7. How can you create a strong name for a .NET assembly? With the help of Strong Name tool (sn.exe).
8. Where’s global assembly cache located on the system? Usually
C:\winnt\assembly or C:\windows\assembly.
9. Can you have two files with the same file name in GAC? Yes, remember that GAC is a very special folder, and while normally you
would not be able to place two files with the same name into a Windows folder, GAC differentiates by version number as well, so it’s possible for MyApp.dll and MyApp.dll to co-exist in GAC if the first one is version 1.0.0.0 and the second one is 1.1.0.0.
10.So let’s say I have an application that uses MyApp.dll assembly, version 1.0.0.0. There is a security bug in that assembly, and I publish the patch, issuing it under name MyApp.dll 1.1.0.0. How do I tell the client applications that are already installed to start using this new MyApp.dll? Use publisher policy. To configure a publisher policy, use the publisher policy configuration file, which uses
a format similar app .config file. But unlike the app .config file, a publisher policy file needs to be compiled into an assembly and placed
in the GAC.
11.What is delay signing? Delay signing allows you to place a shared assembly in the GAC by signing the assembly with just the public key. This allows the assembly to be signed with the private key at a later stage, when the development process is complete and the component or assembly is ready to be deployed. This process enables developers to work with shared assemblies as if they were strongly named, and it secures the private key of the signature from being accessed at different stages of development.
13. Class Library
13.1 Threads
13.1.1 How do I spawn a thread?
Create an instance of a System.Threading.Thread object, passing it an instance of a ThreadStart delegate that will be executed on the new thread. For example:
class MyThread
{
public MyThread( string initData )
{
m_data = initData;
m_thread = new Thread( new ThreadStart(ThreadMain) );
m_thread.Start();
}
// ThreadMain() is executed on the new thread. private void ThreadMain()
{
Console.WriteLine( m_data );
}
public void WaitUntilFinished()
{
m_thread.Join();
}
private Thread m_thread;
private string m_data;
}
In this case creating an instance of the MyThread class is sufficient to spawn the thread and execute the MyThread.ThreadMain() method:
MyThread t = new MyThread( "Hello, world." );
t.WaitUntilFinished();
13.1.2 How do I stop a thread?
There are several options. First, you can use your own communication mechanism to tell the ThreadStart method to finish. Alternatively the Thread class has in-built support for instructing the thread to stop. The two principle methods are Thread.Interrupt() and Thread.Abort(). The former will cause a ThreadInterruptedException to be thrown on the thread when it next goes into a WaitJoinSleep state. In other words, Thread.Interrupt is a polite way of asking the thread to stop when it is no longer doing any useful work. In contrast, Thread.Abort() throws a ThreadAbortException regardless of what the thread is doing. Furthermore, the ThreadAbortException cannot normally be caught (though the ThreadStart's finally method will be executed). Thread.Abort() is a heavy-handed mechanism which should not normally be required.
13.1.3 How do I use the thread pool?
By passing an instance of a WaitCallback delegate to the
ThreadPool.QueueUserWorkItem() method
class CApp
{
static void Main(){
string s = "Hello, World";
ThreadPool.QueueUserWorkItem( new WaitCallback( DoWork ), s );
Thread.Sleep( 1000 ); // Give time for work item to be executed
}
// DoWork is executed on a thread from the thread pool. static void DoWork( object state ){
Console.WriteLine( state );
}
}
13.1.4 How do I know when my thread pool work item has completed?
There is no way to query the thread pool for this information. You must put code into the WaitCallback method to signal that it has completed. Events are useful for this.
13.1.5 How do I prevent concurrent access to my data?
Each object has a concurrency lock (critical section) associated with it. The System.Threading.Monitor.Enter/Exit methods are used to acquire and release this lock. For example, instances of the following class only allow one thread at a time to enter method f():
class C{
public void f(){
try{ Monitor.Enter(this);
...
}
finally{ Monitor.Exit(this);
}
}
}
C# has a 'lock' keyword which provides a convenient shorthand for the code above:
class C{
public void f(){
lock(this){
...
}
}
}
Note that calling Monitor.Enter(myObject) does NOT mean that all access to myObject is serialized. It means that the synchronisation lock associated with myObject has been acquired, and no other thread can acquire that lock until Monitor.Exit(o) is called. In other words, this class is functionally equivalent to the classes above:
class C{
public void f(){
lock( m_object ){
...
}
}
private m_object = new object();
}
Actually, it could be argued that this version of the code is superior, as the lock is totally encapsulated within the class, and not accessible to the user of the object.
13.1.6 Should I use ReaderWriterLock instead of Monitor.Enter/Exit?
Maybe, but be careful. ReaderWriterLock is used to allow multiple threads to read from a data source, while still granting exclusive access to a single writer thread. This makes sense for data access that is mostly read-only, but there are some caveats. First, ReaderWriterLock is relatively poor performing compared to Monitor.Enter/Exit, which offsets some of the benefits. Second, you need to be very sure that the data structures you are accessing fully support multithreaded read access. Finally, there is apparently a bug in the v1.1 ReaderWriterLock that can cause starvation for writers when there are a large number of readers.
13.2 Tracing
13.2.1 Is there built-in support for tracing/logging?
Yes, in the System.Diagnostics namespace. There are two main classes that deal with tracing - Debug and Trace. They both work in a similar way - the difference is that tracing from the Debug class only works in builds that have the DEBUG symbol defined, whereas tracing from the Trace class only works in builds that have the TRACE symbol defined. Typically this means that you should use System.Diagnostics.Trace.WriteLine for tracing that you want to work in debug and release builds, and System.Diagnostics.Debug.WriteLine for tracing that you want to work only in debug builds.
13.2.2 Can I redirect tracing to a file?
Yes. The Debug and Trace classes both have a Listeners property, which is a collection of sinks that receive the tracing that you send via Debug.WriteLine and Trace.WriteLine respectively. By default the Listeners collection contains a single sink, which is an instance of the DefaultTraceListener class. This sends output to the Win32 OutputDebugString() function and also the System.Diagnostics.Debugger.Log() method. This is useful when debugging, but if you're trying to trace a problem at a customer site, redirecting the output to a file is more appropriate. Fortunately, the TextWriterTraceListener class is provided for this purpose.
Here's how to use the TextWriterTraceListener class to redirect Trace output to a file:
Trace.Listeners.Clear();
FileStream fs = new FileStream( @"c:\log.txt", FileMode.Create, FileAccess.Write ); Trace.Listeners.Add( new TextWriterTraceListener( fs ) );
Trace.WriteLine( @"This will be writen to c:\log.txt!" ); Trace.Flush();
Note the use of Trace.Listeners.Clear() to remove the default listener. If you don't do this, the output will go to the file and OutputDebugString(). Typically this is not what you want, because OutputDebugString() imposes a big performance hit.
13.2.3 Can I customise the trace output?
Yes. You can write your own TraceListener-derived class, and direct all output through it. Here's a simple example, which derives from TextWriterTraceListener (and therefore has in-built support for writing to files, as shown above) and adds timing information and the thread ID for each trace line:
class MyListener : TextWriterTraceListener
{
public MyListener( Stream s ) : base(s)
{
}
public override void WriteLine( string s )
{
Writer.WriteLine( "{0:D8} [{1:D4}] {2}", Environment.TickCount - m_startTickCount, AppDomain.GetCurrentThreadId(),
s );
}
protected int m_startTickCount = Environment.TickCount;
}
(Note that this implementation is not complete - the TraceListener.Write method is not overridden for example.)
The beauty of this approach is that when an instance of MyListener is added to the Trace.Listeners collection, all calls to Trace.WriteLine() go through MyListener, including calls made by referenced assemblies that know nothing about the MyListener class.
13.2.4 Are there any third party logging components available?
Log4net is a port of the established log4j Java logging component. log4net is a tool to help the programmer output log statements to a variety of output targets. log4net is a port of the excellent log4j framework to the
.NET runtime. We have kept the framework similar in spirit to the original log4j while taking advantage of new features in the .NET runtime. For more
information on log4net see the features document.
log4net is part of the Apache Logging Services project. The Logging Services project is intended to provide cross-language logging services for purposes of application debugging and auditing.
No comments:
Post a Comment