Google
 

Friday, May 15, 2009

Silverlight 2.0 + IE6 + Compression - BUG!

I have been running into a problem with Silverlight 2.0 when dynamic compression was set on IIS7. I found out that the issue was only with IE6 and not with IE7. After googling for some time I found this article… http://otoole.wordpress.com/2009/03/10/18/

After trying a few things in the article like setting caching off, I decided to call Microsoft and hear what they have to say about all this.

Microsoft replied, and said this is a bug with IE6. What makes things worst is that the bug has no work-around or solution. The only solution will be in Silverlight 3.0, and even that is considered a work-around to the real bug which is in IE6.

At the end, the only way to get our Silverlight app to work with IE6 was to turn compression off, which caused some performance issues…

The issue with Microsoft is still open; I have asked them to validate IE8 and the use of SSL, which has been causing problems too…

Sunday, April 19, 2009

Generic Singleton method

This is a general purpose method to create a singleton. It uses generics and takes two arguments, one is the type of the singleton and the other is the type of the interface you wish to return (this is optional). Notice that the method is thread safe, there is a double check to verify that another thread did not create instance after the first if statement. The idea is to have the lock done only once if possible.

Code looks like this:


private static TInterface GetSingleton(ref TInterface instance)
where TComponent : class, TInterface, new()
{
try
{
if (instance == null)
{
lock (mLockObject)
{
if (instance == null)
{
instance = new TComponent();
}
}
}
return instance;
}
catch (Exception ex)
{
LogException(ex);
throw ex;
}
}

Sunday, March 15, 2009

Jitting at runtime (Jit methods on the fly)

What is Jit



Jit stands for Just in time complication. You can read more about JIT here. However, the idea is that the
code is not fully complied, it is pre-complied. The first time your method is executed, the .NET runtime checks if the method has been complied for the target machine, if it did not then it compiles it on the fly. This is called JIT. This behaviour also causes a delay when executing methods for the first time. The bigger the method, the bigger the delay. I have noticed this delay the most when doing UI applications, the generated code would take a long time to JIT. You can also add performance counters to see how much time your application is jitting. In fact most classes that use generated code, can be good candidate for jitting (typed dataset, UI screens, EDMX...)



NGen


NGen is the alternative solution to runtime Jitting. Everything is complied by the NGen tool and a compiled image is placed within the GAC. At runtime when loading the assembly, the runtime will check for a compiled image based on the assembly name and version, if it finds one it will load it without Jitting. Still, NGen needs to run on the target machine before running the application. NGen is also not as efficient as Jit, that's because Jit executes at runtime and has much more information about the method and how to optimize it. You can read more about NGen here.


Is it possible to control the Jitting



I always wanted to have something to control the jitting at runtime. Similar to the GC class, I can control at runtime when the GC is executed, there is not built in class called Jit that will allow me to Jit certain methods. However, it is possible. The method that allows for this type of functionality is RuntimeHelpers.PrepareMethod Method (RuntimeMethodHandle). However, here is a little warning for you all, in the MSDN article it indicates: The classes in System.Runtime.CompilerServices are for compiler writers' use only.. Still, I decided to use it, there are times that I would like to control when Jitting happens.



JitHelper and the PreJit attribute



The idea is very simple. I want to have a helper class that will jit any method that is marked with an attribute of PreJit. Normally the coder knows which are the heavy methods, this way the coder has the control of marking methods that can take long to jit. For example:


[PreJit]
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Text = "Form1";
}


Notice the PreJit attribute on the method.

PreJit is just a marker attribute. Here is the code for it.


[AttributeUsage(AttributeTargets.Method)]
public class PreJitAttribute : Attribute
{
public PreJitAttribute()
{

}
}



Now, all that is left to do is Jit the methods that are marked with the [PreJit] attribute. Lets take a look at one method that handle jitting based on the type of a CLR class.




private static void PreJitMarkedMethods(Type type)
{
// get the type of all the methods within this instance
var methods = type.GetMethods(BindingFlags.DeclaredOnly |
BindingFlags.NonPublic |
BindingFlags.Public |
BindingFlags.Instance |
BindingFlags.Static);

// for each time, jit methods marked with prejit attribute
foreach (var method in methods)
{
// checks if the [PreJit] Attribute is present
if (ContainsPreJitAttribute(method))
{
// jitting of the method happends here.
RuntimeHelpers.PrepareMethod(method.MethodHandle);
}
}
}

// (helper method) checks if the [PreJit] attribute is present on a method
private static bool ContainsPreJitAttribute(MethodInfo methodInfo)
{
var attributes = methodInfo.GetCustomAttributes(typeof(PreJitAttribute), false);
if (attributes != null)
if (attributes.Length > 0)
{
// attribute found return true
return true;
}

return false;
}


Lets note the important stuff. This method is able to jit all marked methods with the PreJit attribute based on a CLR type




  • Getting all methods, private, public and even static

  • Only Jit methods that have an attribute of [PreJit]
  • On each method we get the MethodInfo object

  • Passing MethodInfo.MethodHandle to PrepareMethod allows us to jit a method



The Jitter



Now that it is possible for me to jit every method within a type, all I have to do is create high level
methods that will allow me to do the following:




  • Jit only methods that are marked with PreJit attribute

  • Jit on a different thread

  • Jit based on an instance (Jit methods within the instance)

  • Jit based on a Type (Jit methods for a given class type)

  • Jit based on an assembly (Jit methods within all the classes in an assembly



Lets see the full class code for the Jitter

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Threading;
using System.Runtime.CompilerServices;

namespace JitHelper
{
public class Jitter
{
public static void PreJit(object instance)
{
PreJitMarkedMethods(instance.GetType());
}


public static void PreJitAll(object instance)
{
PreJitAllMethods(instance.GetType());
}

public static void BeginPreJitAll(object instance)
{
Thread preJitThread = new Thread(() =>
{
PreJitAllMethods(instance.GetType());
});

preJitThread.Name = "PreJittingThread";
preJitThread.Priority = ThreadPriority.Lowest;
preJitThread.Start();

}

public static void PreJit() where T : class
{
PreJitMarkedMethods(typeof(T));
}


public static void PreJitAll() where T : class
{
PreJitAllMethods(typeof(T));
}

public static void BeginPreJitAll() where T : class
{
Thread preJitThread = new Thread(() =>
{
PreJitAllMethods(typeof(T));
});

preJitThread.Name = "PreJittingThread";
preJitThread.Priority = ThreadPriority.Lowest;
preJitThread.Start();
}

public static void PreJitAll(Assembly assembly)
{
var classes = assembly.GetTypes();
foreach (var classType in classes)
{
PreJitAllMethods(classType);
}
}

public static void BeginPreJitAll(Assembly assembly)
{
Thread preJitThread = new Thread(() =>
{
PreJitAll(assembly);
});

preJitThread.Name = "PreJittingThread";
preJitThread.Priority = ThreadPriority.Lowest;
preJitThread.Start();
}


public static void PreJit(Assembly assembly)
{
var classes = assembly.GetTypes();
foreach (var classType in classes)
{
PreJitMarkedMethods(classType);
}
}


public static void BeginPreJit(Assembly assembly)
{
Thread preJitThread = new Thread(() =>
{
PreJit(assembly);
});

preJitThread.Name = "PreJittingThread";
preJitThread.Priority = ThreadPriority.Lowest;
preJitThread.Start();
}

public static void BeginPreJit(object instance)
{
Thread preJitThread = new Thread(() =>
{
PreJit(instance);
});

preJitThread.Name = "PreJittingThread";
preJitThread.Priority = ThreadPriority.Lowest;
preJitThread.Start();
}

private static void PreJitMarkedMethods(Type type)
{
// get the type of all the methods within this instance
var methods = type.GetMethods(BindingFlags.DeclaredOnly |
BindingFlags.NonPublic |
BindingFlags.Public |
BindingFlags.Instance |
BindingFlags.Static);

// for each time, jit methods marked with prejit attribute
foreach (var method in methods)
{
if (ContainsPreJitAttribute(method))
{
// jitting of the method happends here.
RuntimeHelpers.PrepareMethod(method.MethodHandle);
}
}
}


private static void PreJitAllMethods(Type type)
{
// get the type of all the methods within this instance
var methods = type.GetMethods(BindingFlags.DeclaredOnly |
BindingFlags.NonPublic |
BindingFlags.Public |
BindingFlags.Instance |
BindingFlags.Static);

// Jit all methods
foreach (var method in methods)
{
// jitting of the method happends here.
RuntimeHelpers.PrepareMethod(method.MethodHandle);
}
}


private static bool ContainsPreJitAttribute(MethodInfo methodInfo)
{
var attributes = methodInfo.GetCustomAttributes(typeof(PreJitAttribute), false);
if (attributes != null)
if (attributes.Length > 0)
{
return true;
}

return false;
}
}
}


A few notes about the code:


  • Methods beginning with "Begin" are executed on a low priority thread. This allows for background jitting. I have not done a callback feature to know when jitting ends, I don't think it is required, but you are free to modify the class and add it.

  • Method ending with "All", will Jit all methods and not just the one marked as PreJit attribute

  • Not all methods can be PreJit, for example methods marked as DllExport are not .NET methods, so be careful with the All feature. For performance reasons I have not checked for DllExport attribute, but you can add it if needed.

  • Notice that one method uses generics, this is simply so the caller can pass the type via generic without doing typeof operator.



Using the Jitter



I will simply show you an exmaple, the following example everything within Form1 is pre-Jitted.


[STAThread]
static void Main()
{
// Jitting all the methods within Form1 class.
Jitter.PreJitAll();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}


if you want to pre-jit within a thread, then simply use:


[STAThread]
static void Main()
{
Jitter.BeginPreJitAll();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}


Benchmarking


It is not that simple to benchmark this type of code because it really depends how your application works. However, the Jit operation happends the first time a method is executed. So the first time of any method will cause a delay. I have created a windows form full of text boxes controls, and I used the Jitter to Jit everything within the form class. On the form show event I display the time it took to show the form:

Without using the jitter: ~0.12 milliseconds
With the Jitter: ~0.12 milliseconds
Timing after Jitting: ~0.09 milliseconds


  • With the Jitter or without it, it took about the same amount of time to show the form.

  • Without timing the Jitter, just the load operation after the Jit, it took 0.09 miliseconds to show

  • Overall it means that the Jitter class can have a significate performance improvment at runtime, if a class is jitted before it is being used.


Conclusion




Let me first say that I coded this class mostly because I wanted to have the control over Jitting. But overall .NET runtime does a very good job Jitting when needed. The same way we should not call GC.Collect() we should not call Jitting functions. Having said that, there are times it would be nice to control Jitting and have an alternative to NGen. Use this tool only if you have a performance issue, or a startup timing issue. If you do not have a performance issue - do not use this. This class also uses reflection to find out the methods to Jit. Reflection is slow, which is another reason to avoid using this class unless required. You should consider trying pre-jitting your classes when you are using generated code classes, such as typed dataset, LINQ to entities, or winform UI classes.

Even if you are not planning to use the Jitter class, it is better to have the Jitter class and not need it, then need it and not have it.

Thank you for reading. Have a nice day, and happy .Netting.



Wednesday, January 28, 2009

SDF (Compact sql database) with .NET 3.5SP1 Buggy with Entity Framework

I just can't believe Microsoft will ship this technology with such major bugs within it. If you are looking into SDF files with support of entity framework, you might want to look into the major bugs they are having. For example, you will not be able to use a string variable in a compare operation with a LINQ statement. Sounds basic, but still it does not work. Look at the blob on this bug

http://social.msdn.microsoft.com/forums/en-US/sqlce/thread/b6bac277-cf66-4c74-a0b3-e48abedbd161/

I wonder if Microsoft forgot to unit-test this stuff before shipping.

Thursday, January 8, 2009

How to find an avaiable TCP port

This simple method will return the next avaiable TCP port



      private static int GetAvaiablePort()
{
IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, 0);
using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
socket.Bind(endPoint);
IPEndPoint local = (IPEndPoint)socket.LocalEndPoint;
return local.Port;
}
}

Tuesday, December 30, 2008

DM-V-VM

Links for DataModel View ViewModel Pattern


https://blogs.msdn.com/dancre/archive/tags/DM-V-VM/default.aspx

http://www.nikhilk.net/Entry.aspx?id=198

http://www.codeproject.com/KB/WPF/TreeViewWithViewModel.aspx

ICommand for Silverlight with Attached Behaviors

http://www.codeproject.com/KB/WPF/AttachedBehaviors.aspx

Monday, December 29, 2008

Understanding SynchronizationContext Part III


Introduction


This article is the last part of the 3 part series on SynchronizationContext, SynchronizationContext is a class introduced by .NET 2.0 with little documentation or explanation of how to use it. I have tried to explain in part one how to use this class, and in part two how to create your own SynchronizationContext. In part two, I have showed how to build a SynchronizationContext that will marshal code from any .NET thread into a STA thread. I have done this so I can execute COM code that needs to run on the STA thread. The next step is to create a WCF service that will execute all its service operations on the STA thread (using the SynchronizationContext I provided in part II). In this article, I will show you how to configure WCF to provide a custom STA SynchronizationContext so each method on a WCF service will execute on the same STA thread. This will allow me to provide a simple programming model, that will be fully compatible with COM and I will not need to worry about thread safety because all my code will run within the same thread.



WCF - The Power



I will not even try to give a full explanation of WCF here, WCF is vast in functionality and does much more then just "remoting" or web services. I am starting to believe that WCF should be treated as a runtime rather then a communication framework. WCF provides us "out of the box" the following programming models:




  • built-in support for error handling


  • built-in support for concurrency


  • built-in support for security


  • built-in support for transaction


  • built-in support for data encryption


  • built-in support for durable services


  • built-in support for method interception and inspection (AOP)


  • built-in support for one way communication, and callbacks


  • and much more...



Just listen to this arcast, where Juval Lowy believes every class should be a WCF class. http://channel9.msdn.com/shows/ARCast+with+Ron+Jacobs/ARCastTV-Every-Class-a-WCF-Service-with-Juval-Lowy/ At first, I said to myself, this is too much, every class to be a WCF class is just insane. But the more I looked at WCF and what it had to offer, the more it made sense to me. WCF is a very extensible framework, allowing the developer to do a lot of custom configuration. For example providing a SynchronizationContext for your service is something you will not be able to do within native .NET classes, but only in WCF (and that's just one feature among many). Although I must say I did not go as far as making each class a WCF class, I have decided to make each component a WCF service, even if I don't plan to run my component remotly, I still believe the benefits of the WCF runtime are worth coding my components as WCF services. Bottom line, WCF is more then web services or remoting services, it provides a solid programming model that apply in every type of development. If you don't know WCF, I strongly recommend you learn it, it is by far one of the better frameworks Micrsooft have released. For this article, I assume you have basic knowledge of WCF services.



A simple WCF Service


Let me just say this right away, I have coded a WCF service for this article just for testing. I do not recommend you code services the way that I have. To be more specific, in my code the service implementation and the service contact are within the same assembly - this is not recommended. However, because I am dealing with testing my SynchronizationContext within a prototype/testing project, I wanted to keep the number of assemblies and code to a minimum. Normally, when I code a WCF service I have 3 projects.

  • Project containing the service contact (interface) and possibly any data contacts (DTOs)


  • Project containing the service implementation


  • Project hosting the service (optional)


So please no bashing, I am stating it here that the code is just for testing and not for production, now that we got it out of the way, let me show the service contact and implementation



[ServiceContract]
public interface IStaService
{
[OperationContract]
string DoWorkOnSTAThread(string state);
}


There is really not much to say about this service, it is very simple. Let me show you the implementation of this service



public class StaService : IStaService
{
public string DoWorkOnSTAThread(string state)
{
ApartmentState aptState = Thread.CurrentThread.GetApartmentState();
if (aptState == ApartmentState.STA)
Trace.WriteLine("Using STA thread");

int id = Thread.CurrentThread.ManagedThreadId;
Trace.WriteLine("WCF current thread: " + id);
return "processed by " + aptState.ToString() + " Thread id: " + id.ToString();
}
}


Notes:




  • DoWorkOnSTAThread will be the method I plan to execute on the STA thread, so I coded some tracking code to make sure I am running this method on the STA thread. I check the ApartmentState and make sure it is an ApartmentState.STA


  • I also log the thread ID, considering I want all my code to run on the same STA thread, the ID should always be the same


  • However I did not write any code to indicate using the STA Sync Context, so for now, STA thread marshaling is not used



Testing our service



We will be running our service a few times, so lets learn how to test it. My service is hosted using webdev, and it is running as a web service. To test it, I have used the WCF test client applicaiton.It can normally be found at "C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\WcfTestClient.exe" by calling DoWorkOnSTAThread multiple times, I get the following output




Output window:


WCF current thread: 12
WCF current thread: 12
WCF current thread: 11
WCF current thread: 11
WCF current thread: 11
WCF current thread: 13
WCF current thread: 10
WCF current thread: 11
WCF current thread: 10
WCF current thread: 10
WCF current thread: 13


To find out the service behavior, you can view the ServiceDescription within a custom ServiceHost (I will show the custom service host code later in the article)





Notice that I am running the same method on multiple threads. This is because by default WCF created my service using PerSession InstanceContextMode and ConcurrencyMode of Single (see image above). This means that the method will be executed one at the time, but each time it is executed by a thread assigned by the thread pool. First, you should avoid using PerSession for your services, PerSession simply does not scale, I consider it evil for coding scalable services, so, I am going to change the service behavior



[ServiceBehavior(UseSynchronizationContext=true, ConcurrencyMode=ConcurrencyMode.Multiple,
InstanceContextMode=InstanceContextMode.PerCall)]
public class StaService : IStaService
{
public string DoWorkOnSTAThread(string state)
{
ApartmentState aptState = Thread.CurrentThread.GetApartmentState();
if (aptState == ApartmentState.STA)
Trace.WriteLine("Using STA thread");

int id = Thread.CurrentThread.ManagedThreadId;
Trace.WriteLine("WCF current thread: " + id);
//throw new Exception("boom");
return "processed by " + aptState.ToString() + " Thread id: " + id.ToString();
}
}


Using the WCF service behavior attribute [ServiceBehavior(UseSynchronizationContext=true, ConcurrencyMode=ConcurrencyMode.Multiple, InstanceContextMode=InstanceContextMode.PerCall)] I ask WCF to create this service using InstanceContextMode.PerCall, this means every method call will create an instance of the service, and as soon as the method completes the instance is destroyed. Using ConcurrencyMode.Multiple allows for clients to execute methods within this service concurrently, allowing multiple threads to execute the same method at the same time. UseSynchronizationContext=true means that I ask the service to use the SynchronizationContext attached to the host's thread. Using this new service behavior, lets see our output by executing the method 3 times:



WCF current thread: 12
WCF current thread: 9
WCF current thread: 6


Same results more or less... Our service can scale better, but still have no control on which thread the code is executed on.



Providing your service a SynchronizationContext



You noticed that no matter if the service is using single or multiple concurrency mode, in both the invocation is controlled by WCF using different threads from the thread pool. In order to provide your own SynchronizationContext you have two choices:




  • Set the SynchronizationContext on the hosting thread before opening the host


  • Create your own ServiceBehavior and override the SynchronizationContext on the service endpoint



I will explore the second option simply because we don't always create our own hosting program and in many cases the hosting is done in WAS or IIS. Let me show you the ServiceBehvior attribute I created to use STA thread synchronization.



public class StaServiceBehaviorAttribute : Attribute, IContractBehavior, IServiceBehavior
{
StaSynchronizationContext mStaContext;
public StaServiceBehaviorAttribute()
{
mStaContext = new StaSynchronizationContext();
}
#region IContractBehavior Members

void IContractBehavior.AddBindingParameters(ContractDescription contractDescription,
ServiceEndpoint endpoint,
System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
{

}

void IContractBehavior.ApplyClientBehavior(ContractDescription contractDescription,
ServiceEndpoint endpoint,
System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
{

}

void IContractBehavior.ApplyDispatchBehavior(ContractDescription contractDescription,
ServiceEndpoint endpoint,
System.ServiceModel.Dispatcher.DispatchRuntime dispatchRuntime)
{
dispatchRuntime.SynchronizationContext = mStaContext;
}

void IContractBehavior.Validate(ContractDescription contractDescription,
ServiceEndpoint endpoint)
{

}

#endregion

#region IServiceBehavior Members

void IServiceBehavior.AddBindingParameters(ServiceDescription serviceDescription,
System.ServiceModel.ServiceHostBase serviceHostBase,
System.Collections.ObjectModel.Collection endpoints,
System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
{

}

void IServiceBehavior.ApplyDispatchBehavior(ServiceDescription serviceDescription,
System.ServiceModel.
ServiceHostBase serviceHostBase)
{

}

void IServiceBehavior.Validate(ServiceDescription serviceDescription,
System.ServiceModel.ServiceHostBase serviceHostBase)
{
serviceHostBase.Closed += delegate
{
mStaContext.Dispose();
};
}

#endregion
}


By creating my own custom ServiceBehvior attribute I can set certain settings that are otherwise not available to me.



Notice that I am creating the StaSynchronizationContext at the constructor



public StaServiceBehaviorAttribute()
{
mStaContext = new StaSynchronizationContext();
}


The other most important part is implementing the ApplydispatchBehvior method. This method will be executed once on each endpoint within your service. It allows me to override the default SynchronizationContext with my own custom one.



void IContractBehavior.ApplyDispatchBehavior(ContractDescription contractDescription,
ServiceEndpoint endpoint,
System.ServiceModel.Dispatcher.DispatchRuntime dispatchRuntime)
{
dispatchRuntime.SynchronizationContext = mStaContext;
}


To make sure my STA thread ends correctly, I have also modified the IServiceBehavior.Validate and provided an event handler for closing the host



void IServiceBehavior.Validate(ServiceDescription serviceDescription,
System.ServiceModel.ServiceHostBase serviceHostBase)
{
serviceHostBase.Closed += delegate
{
mStaContext.Dispose();
};
}


Using the STA Synchronization Context



Let's take another look at our service, now that we have created own ServiceBehavior to apply a custom Synchronization Context



[StaServiceBehaviorAttribute]
[ServiceBehavior(UseSynchronizationContext=true, ConcurrencyMode=ConcurrencyMode.Multiple,
InstanceContextMode=InstanceContextMode.PerCall)]
public class StaService : IStaService
{
public string DoWorkOnSTAThread(string state)
{
ApartmentState aptState = Thread.CurrentThread.GetApartmentState();
if (aptState == ApartmentState.STA)
Trace.WriteLine("Using STA thread");

int id = Thread.CurrentThread.ManagedThreadId;
Trace.WriteLine("WCF current thread: " + id);
//throw new Exception("boom");
return "processed by " + aptState.ToString() + " Thread id: " + id.ToString();
}
}



  • Notice that I kept the WCF service behavior to use PerCall and ConcurrentcyMode.Multiple. Considering we are planning to marshal our code to one STA thread, using ConcurrencyMode.Single will have the same behavior as ConcurrencyMode.Multiple


  • Notice I have placed my StaServiceBehaiorAttribue on the service, this will create the STA thread, and apply a STA synchronization context on all the endpoints my service exposes (in the example I only have one endpoint)



Very well, lets try it, but using the WCF client tool, I have send multiple request to my service and here are the results



Using STA thread
WCF current thread: 9
Using STA thread
WCF current thread: 9
Using STA thread
WCF current thread: 9
Using STA thread
WCF current thread: 9
Using STA thread
WCF current thread: 9
Using STA thread
WCF current thread: 9
Using STA thread
WCF current thread: 9
Using STA thread
WCF current thread: 9



  • Notice that all the calls to the WCF method are executed on thread 9


  • Notice that thread 9 is a STA thread as we expected



Now I am able to control on which thread the WCF service is executing on.



A word about hosting



Notice that using this method you can control the synchronization context of your service no matter what hosting method you choose. If you are hosting using a console application, you could set the synchronization context to STA (using the SynchronizationContext.SetSynchronizationContext) before opening the host, it will have the same effect.I tried to use a custom ServiceHostFactory and set the synchronization context there, but it did not work. Let me show you the custom ServiceHostFactory and the custom ServiceHost.



public class StaCustomHostFactory : ServiceHostFactory
{
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
return new StaCustomHost(serviceType, baseAddresses);
}
}


public class StaCustomHost : ServiceHost
{
public StaCustomHost(Type serviceType, params Uri[] baseAddresses) :
base(serviceType, baseAddresses)
{

}

protected override void InitializeRuntime()
{
int id = Thread.CurrentThread.ManagedThreadId;
base.InitializeRuntime();
}

protected override void ApplyConfiguration()
{
int id = Thread.CurrentThread.ManagedThreadId;
// get the configuration from the app.config first
base.ApplyConfiguration();

// create the STA Thread Sync object and attach it to this hosting
// thread.
StaSynchronizationContext staContext = new StaSynchronizationContext();
SynchronizationContext.SetSynchronizationContext(staContext);
}
}


<%@ ServiceHost 
Language="C#" Debug="true"
Factory="StaServiceHost.StaCustomHostFactory"
Service="TestStaService.StaService"
CodeBehind="StaService.svc.cs" %>


Notice I set the SynchronizationContext within the ApplyConfiguration method. WCF will take whatever SynchronizationContext is set on the host's thread and use it for each invocation. However it did not work at all. I don't know exactly why, but the only explanation I can come up with is that the code within ApplyConfiguration does not run within the same thread as the ServiceHost.Open. Considering that the host is opened by webdev or IIS, I really don't know how to set the synchronization context on these threads. Therefore, I recommend you stick to using custom service behavior as I have shown before for overriding the synchronization context of your service's endpoints.





One little comment about closing the host, as you seen in part II, the STA thread is created as soon as the STA SynchronizationContext object is created. In this case it is created within the service behavior. It is important that this thread ends when the host closes. That's the reason I have coded this event handler:



void IServiceBehavior.Validate(ServiceDescription serviceDescription,
System.ServiceModel.ServiceHostBase serviceHostBase)
{
serviceHostBase.Closed += delegate
{
mStaContext.Dispose();
};
}


I have tested this code by stopping the webdev process and placing a break-point on the event handler. I validated that the STA thread is exiting when webdev is closing. Thanks for small WCF miracles.



Is WCF using Send or Post?



You might be wondering if the Send or the Post of our sync-context is used. I really didn't know, so I set a breakpoint on both the Send and Post methods, and found out that WCF always uses the Post method. I have changed the service concurency-mode to ConcurrencyMode.Single and still Post was used. So using Single or Multiple concurency, in both cases the Post method is used to marshal code into the STA thread. What about exceptions? Notice I have modified my service to throw an exception:



   [StaServiceBehaviorAttribute]
[ServiceBehavior(UseSynchronizationContext=true, ConcurrencyMode=ConcurrencyMode.Multiple,
InstanceContextMode=InstanceContextMode.PerCall)]
public class StaService : IStaService
{
public string DoWorkOnSTAThread(string state)
{
ApartmentState aptState = Thread.CurrentThread.GetApartmentState();
if (aptState == ApartmentState.STA)
Trace.WriteLine("Using STA thread");

int id = Thread.CurrentThread.ManagedThreadId;
Trace.WriteLine("WCF current thread: " + id);
throw new Exception("boom");
//return "processed by " + aptState.ToString() + " Thread id: " + id.ToString();
}
}


Initially, I believed that this might cause the STA thread to terminate, it is an unhandled exception running on the STA thread, but WCF does handle the exception for you. So the STA thread does not end even if you throw exceptions within the STA thread. WCF catches any unhanlded exception and converts them to FaultException on the client thread. This saves our STA thread from ending, so it keeps running regardless if exceptions are thrown. Thank god for another WCF miracle.



Conclusion



In this article I got into the inner working of WCF and grabbed control on "where" a service method is executed on. I am able to "tell" WCF to marshal all the method calls on a STA thread, allowing us not to worry about calling COM objects that are designed to work on the STA thread. This will also allow you to pop UI within your service method, but I really don't recommend it. By marshaling the code yourself, you can add additional logic to log and validate each invocation. You might even add security at this level and refuse marshaling a call if it does not fit a certain criteria. However, do not use this as a wild card, service side method interception can also do the same thing. Still, now that you know about this feature, you might find a good use for it within your projects.


Thank you for reading and happy dot netting.