您的位置:首页 > 编程语言 > C#

c# 编码规范4

2009-01-22 14:20 375 查看

Framework-Specific Guidelines

Multithreading

Use synchronization domains.
Avoid manual synchronization, because that often leads to deadlocks and race
conditions.

Never call outside your synchronization domain.

Manage asynchronous call completion on a callback method. Do
not wait, poll, or block for completion.

Always name your threads:
Thread currentThread = Thread.CurrentThread;
string threadName = "Main UI Thread";
currentThread.Name = threadName;


The name is traced in the debugger Threads window, making debug
sessions more productive.

Do not call Suspend( ) or Resume( ) on a
thread.

Do not call Thread.Sleep( ), except in the following
conditions:

Thread.Sleep(0) is an acceptable optimization
technique to force a context switch.

Thread.Sleep( ) is acceptable in testing or simulation
code.

Do not call THRead.SpinWait( ).

Do not call Thread.Abort( ) to terminate threads. Use
a synchronization object instead to signal the thread to terminate.

Avoid explicitly setting the thread priority to control
execution. You can set the thread priority based on task semantics (such as
ThreadPriority.BelowNormal for a screensaver).

Do not read the value of the ThreadState property. Use
Thread.IsAlive( ) to determine whether the thread is dead or
alive.

Do not rely on setting the thread type to background thread for
application shutdown. Use a watchdog or other monitoring entity to
deterministically kill threads.

Do not use the thread local storage unless thread affinity is
guaranteed.

Do not call Thread.MemoryBarrier( ).

Never call Thread.Join( ) without checking that you
are not joining your own thread:
void WaitForThreadToDie(Thread thread)
{
Debug.Assert(Thread.CurrentThread.ManagedThreadId != thread.ManagedThreadId);
thread.Join( );
}


Always use the lock( ) statement rather than explicit
Monitor manipulation.

Always encapsulate the lock( ) statement inside the
object it protects:
public class MyClass
{
public void DoSomething( )
{
lock(this)
{...}
}
}


You can use synchronized methods instead of writing the
lock( ) statement yourself.

Avoid fragmented locking.

Avoid using a Monitor to wait or pulse objects. Use
manual or auto-reset events instead.

Do not use volatile variables. Lock your object or fields
instead to guarantee deterministic and thread-safe access. Do not use
THRead.VolatileRead( ), Thread.VolatileWrite( ), or the
volatile modifier.

Avoid increasing the maximum number of threads in the thread
pool.

Never stack lock( ) statements, because that does not
provide atomic locking:
MyClass obj1 = new MyClass( );
MyClass obj2 = new MyClass( );
MyClass obj3 = new MyClass( );

//Do not stack lock statements
lock(obj1)
lock(obj2)
lock(obj3)
{
obj1.DoSomething( );
obj2.DoSomething( );
obj3.DoSomething( );
}


Use WaitHandle.WaitAll( )
instead.

Serialization

Prefer the binary formatter.

Mark serialization event-handling methods as private.

Use the generic IGenericFormatter interface.

Always mark non-sealed classes as serializable.

When implementing IDeserializationCallback on a
non-sealed class, make sure to do so in a way that allows subclasses to call the
base class implementation of OnDeserialization( ).

Always mark unserializable member variables as
non-serializable.

Always mark delegates on a serialized class as non-serializable
fields:
[Serializable]
public class MyClass
{
[field:NonSerialized]
public event EventHandler MyEvent;
}


Remoting

Prefer administrative configuration to programmatic
configuration.

Always implement IDisposable on single-call
objects.

Always prefer a TCP channel and a binary format when using
remoting, unless a
firewall is present.

Always provide a null lease for a singleton
object:
public class MySingleton : MarshalByRefObject
{
public override object InitializeLifetimeService( )
{
return null;
}
}


Always provide a sponsor for a client-activated object. The
sponsor should return the initial lease time.

Always unregister the sponsor on client application
shutdown.

Always put remote objects in class libraries.

Avoid using SoapSuds.exe.

Avoid hosting in IIS.

Avoid using uni-directional channels.

Always load a remoting configuration file in Main( ),
even if the file is empty and the application does not use remoting:
static void Main( )
{
RemotingConfigurationEx.Configure( );
/* Rest of Main( )  */
}


Avoid using Activator.GetObject( ) and
Activator.CreateInstance( ) for remote object activation. Use
new instead.

Always register port 0 on the client side, to allow
callbacks.

Always elevate type filtering to Full on both client and host,
to allow callbacks.

Security

Always demand your own strong name on assemblies and components
that are private to the application, but are public (so that only you can use
them):
public class PublicKeys
{
public const string MyCompany = "1234567894800000940000000602000000240000"+
"52534131000400000100010007D1FA57C4AED9F0"+
"A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C83"+
"4C99921EB23BE79AD9D5DCC1DD9AD23613210290"+
"0B723CF980957FC4E177108FC607774F29E8320E"+
"92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99"+
"285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF"+
"0FC4963D261C8A12436518206DC093344D5AD293";
}

[StrongNameIdentityPermission(SecurityAction.LinkDemand,
PublicKey = PublicKeys.MyCompany)]
public class MyClass
{...}


Apply encryption and security protection on application
configuration files.

When importing an interop method, assert unmanaged code
permission and demand appropriate permission instead:
[DllImport("user32",EntryPoint="MessageBoxA")]
private static extern int Show(IntPtr handle,string text,string caption,
int msgType);
[SecurityPermission(SecurityAction.Assert,UnmanagedCode = true)]
[UIPermission(SecurityAction.Demand,
Window = UIPermissionWindow.SafeTopLevelWindows)]
public static void Show(string text,string caption)
{
Show(IntPtr.Zero,text,caption,0);
}


Do not suppress unmanaged code access via the
SuppressUnmanagedCodeSecurity attribute.

Do not use the /unsafe switch of TlbImp.exe. Wrap the RCW in managed code so that you
can assert and demand permissions declaratively on the wrapper.

On server machines, deploy a code access security policy that
grants only Microsoft, ECMA, and self (identified by a strong name) full trust.
Code originating from anywhere else is implicitly granted nothing.

On client machines, deploy a security policy that grants client
application only the permissions to execute, to call back the server, and to
potentially display user interface. When not using ClickOnce, client application
should be identified by a strong name in the code groups.

To counter a luring attack, always refuse at the assembly level
all permissions not required to perform the task at hand:
[assembly:UIPermission(SecurityAction.RequestRefuse,
Window=UIPermissionWindow.AllWindows)]


Always set the principal policy in every Main( )
method to Windows:
public class MyClass
{
static void Main( )
{
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
}
//other methods
}


Never assert a permission without demanding a different
permission in its place.

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息