﻿<?xml version="1.0" encoding="utf-8"?><Type Name="DecorateThreadsRule" FullName="Gendarme.Rules.Concurrency.DecorateThreadsRule"><TypeSignature Language="C#" Value="public sealed class DecorateThreadsRule : Gendarme.Framework.Rule, Gendarme.Framework.IMethodRule" /><TypeSignature Language="ILAsm" Value=".class public auto ansi sealed beforefieldinit DecorateThreadsRule extends Gendarme.Framework.Rule implements class Gendarme.Framework.IMethodRule, class Gendarme.Framework.IRule" /><AssemblyInfo><AssemblyName>Gendarme.Rules.Concurrency</AssemblyName><AssemblyVersion>4.2.0.0</AssemblyVersion></AssemblyInfo><Base><BaseTypeName>Gendarme.Framework.Rule</BaseTypeName></Base><Interfaces><Interface><InterfaceName>Gendarme.Framework.IMethodRule</InterfaceName></Interface></Interfaces><Attributes><Attribute><AttributeName>Gendarme.Framework.EngineDependency(typeof(Gendarme.Framework.Engines.OpCodeEngine))</AttributeName></Attribute><Attribute><AttributeName>Gendarme.Framework.Problem("Threaded code is not decorated as threaded, a threading attribute is improperly used, or the assembly does not use ThreadModelAttribute.")</AttributeName></Attribute><Attribute><AttributeName>Gendarme.Framework.Solution("Use the correct threading attribute or disable the defect.")</AttributeName></Attribute></Attributes><Docs><summary>
             This rule is designed to help you precisely specify the threading semantics supported
             by your code. This is valuable because it forces you to think clearly about the semantics
             required of the code, the semantics are explicitly visible in the code, and the rule verifies
              that the specification remains consistent.
            
             In order to do this the rule relies on an attribute which allows you to declare that your
             code can only run under the main thread, that it can run under an arbitrary thread,
             that it can run under multiple threads if the execution is serialized, or that the code
             is fully concurrent.
            
             The rule enforces the following constraints:
             <list><item>Thread entry points cannot be main thread.</item><item>MainThread code can call everything, AllowEveryCaller code can be called by 
             everything, SingleThread can call SingleThread/Serializable/Concurrent, and Serializable/
             Concurrent can call Serializable/Concurrent.</item><item>Delegates must be able to call the methods they are bound to.</item><item>An override of a base method or an implementation of an interface method must 
             use the same threading model as the original method.</item><item>A delegate used with a threaded event must use the same threading model as the 
             event.</item><item>Serializable cannot be applied to static methods and static methods of serializeable 
             types do not inherit it from their types. (The rationale here is that there is normally nothing 
             that can be used to serialize access to static methods other  than the type which is a bad 
             idea, see [http://bytes.com/groups/net-c/249277-dont-lock-type-objects]).</item></list>
            
             When adding the attributes to a non-trivial amount of threaded code it seems best to focus
             on one thread at a time so that it is easier to understand how the methods interact and which
             threading model needs to be used by them. While doing this the defects for the other threads
             can be temporarily suppressed using gendarme's --ignore switch.
             </summary><remarks>To be added.</remarks><example>
             Bad example:
             <code>
             internal sealed class Wrapper : IDisposable
             {
             	// Finalizers execute from a worker thread so the rule will complain
             	// if they are main thread.
             	~Wrapper ()
             	{
             		Dispose (false);
             	}
             	
             	public void Dispose ()
             	{
             		Dispose (true);
             		GC.SuppressFinalize (this);
             	}
             	
             	private void Dispose (bool disposing)
             	{
             		if (!Disposed) {
             			Disposed = true;
             		}
             	}
             	
             	private bool Disposed { get; set; }
             }
             </code></example><example>
             Good example:
             <code>
             public enum ThreadModel {
             	// The code may run safely only under the main thread (this is the 
             	// default for code in the assemblies being checked).
             	MainThread = 0x0000,
             	
             	// The code may run under a single arbitrary thread.
             	SingleThread = 0x0001,
             	
             	// The code may run under multiple threads, but only if the 
             	// execution is serialized (e.g. by user level locking).
             	Serializable = 0x0002,
             	
             	// The code may run under multiple threads concurrently without user 
             	// locking (this is the default for code in the System/Mono namespaces).
             	Concurrent = 0x0003,
             	
             	// Or this with the above for the rare cases where the code cannot be
             	// shown to be correct using a static analysis.
             	AllowEveryCaller = 0x0008,
             }
             
             // This is used to precisely specify the threading semantics of code. Note 
             // that Gendarme's DecorateThreadsRule will catch problematic code which 
             // uses these attributes (such as concurrent code calling main thread code).
             [Serializable]
             [AttributeUsage (AttributeTargets.Class | AttributeTargets.Struct | 
             AttributeTargets.Interface | AttributeTargets.Delegate | 
             AttributeTargets.Method | AttributeTargets.Event | AttributeTargets.Property,
             AllowMultiple = false, Inherited = false)]
             public sealed class ThreadModelAttribute : Attribute {
             	public ThreadModelAttribute (ThreadModel model)
             	{
             		Model = model;
             	}
             	
             	public ThreadModel Model { get; set; }
             }
            
             internal sealed class Wrapper : IDisposable
             {
             	[ThreadModel (ThreadModel.SingleThread)]
             	~Wrapper ()
             	{
             		Dispose (false);
             	}
             	
             	public void Dispose ()
             	{
             		Dispose (true);
             		GC.SuppressFinalize (this);
             	}
             	
             	// This is called from both the finalizer thread and the main thread
             	// so it must be decorated. But it only executes under one thread
             	// at a time so we can use SingleThread instead of Concurrent.
             	[ThreadModel (ThreadModel.SingleThread)]
             	private void Dispose (bool disposing)
             	{
             		if (!Disposed) {
             			Disposed = true;
             		}
             	}
             	
             	// This is called from a threaded method so it must also be
             	// threaded.
             	[ThreadModel (ThreadModel.SingleThread)]
             	private bool Disposed { get; set; }
             }
             </code></example></Docs><Members><Member MemberName=".ctor"><MemberSignature Language="C#" Value="public DecorateThreadsRule ();" /><MemberSignature Language="ILAsm" Value=".method public hidebysig specialname rtspecialname instance void .ctor() cil managed" /><MemberType>Constructor</MemberType><AssemblyInfo><AssemblyVersion>4.2.0.0</AssemblyVersion></AssemblyInfo><Parameters /><Docs><summary>To be added.</summary><remarks>To be added.</remarks></Docs></Member><Member MemberName="CheckMethod"><MemberSignature Language="C#" Value="public Gendarme.Framework.RuleResult CheckMethod (Mono.Cecil.MethodDefinition method);" /><MemberSignature Language="ILAsm" Value=".method public hidebysig newslot virtual instance valuetype Gendarme.Framework.RuleResult CheckMethod(class Mono.Cecil.MethodDefinition method) cil managed" /><MemberType>Method</MemberType><AssemblyInfo><AssemblyVersion>4.2.0.0</AssemblyVersion></AssemblyInfo><ReturnValue><ReturnType>Gendarme.Framework.RuleResult</ReturnType></ReturnValue><Parameters><Parameter Name="method" Type="Mono.Cecil.MethodDefinition" /></Parameters><Docs><param name="method">To be added.</param><summary>To be added.</summary><returns>To be added.</returns><remarks>To be added.</remarks></Docs></Member><Member MemberName="DefectCount"><MemberSignature Language="C#" Value="public int DefectCount { get; }" /><MemberSignature Language="ILAsm" Value=".property instance int32 DefectCount" /><MemberType>Property</MemberType><AssemblyInfo><AssemblyVersion>4.2.0.0</AssemblyVersion></AssemblyInfo><ReturnValue><ReturnType>System.Int32</ReturnType></ReturnValue><Docs><summary>To be added.</summary><value>To be added.</value><remarks>To be added.</remarks></Docs></Member><Member MemberName="Initialize"><MemberSignature Language="C#" Value="public override void Initialize (Gendarme.Framework.IRunner runner);" /><MemberSignature Language="ILAsm" Value=".method public hidebysig virtual instance void Initialize(class Gendarme.Framework.IRunner runner) cil managed" /><MemberType>Method</MemberType><AssemblyInfo><AssemblyVersion>4.2.0.0</AssemblyVersion></AssemblyInfo><ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue><Parameters><Parameter Name="runner" Type="Gendarme.Framework.IRunner" /></Parameters><Docs><param name="runner">To be added.</param><summary>To be added.</summary><remarks>To be added.</remarks></Docs></Member><Member MemberName="OnAssembly"><MemberSignature Language="C#" Value="public void OnAssembly (object sender, Gendarme.Framework.RunnerEventArgs e);" /><MemberSignature Language="ILAsm" Value=".method public hidebysig instance void OnAssembly(object sender, class Gendarme.Framework.RunnerEventArgs e) cil managed" /><MemberType>Method</MemberType><AssemblyInfo><AssemblyVersion>4.2.0.0</AssemblyVersion></AssemblyInfo><ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue><Parameters><Parameter Name="sender" Type="System.Object" /><Parameter Name="e" Type="Gendarme.Framework.RunnerEventArgs" /></Parameters><Docs><param name="sender">To be added.</param><param name="e">To be added.</param><summary>To be added.</summary><remarks>To be added.</remarks></Docs></Member><Member MemberName="TearDown"><MemberSignature Language="C#" Value="public override void TearDown ();" /><MemberSignature Language="ILAsm" Value=".method public hidebysig virtual instance void TearDown() cil managed" /><MemberType>Method</MemberType><AssemblyInfo><AssemblyVersion>4.2.0.0</AssemblyVersion></AssemblyInfo><ReturnValue><ReturnType>System.Void</ReturnType></ReturnValue><Parameters /><Docs><summary>To be added.</summary><remarks>To be added.</remarks></Docs></Member></Members></Type>