none
WCF, static data and AppDomains RRS feed

  • Question

  • We are developing a WebSocket based, per session (i.e. InstanceContextMode = InstanceContextMode.PerSession) WCF service. The service will make heavy use of our existing code base for server side image rendering, some of which is highly multi-threaded and parts of which are also native code. The code makes use of static data (singletons, local static variables, etc) in both the native and managed parts.

    We were working on the assumption that each WCF session is launched into its own AppDomain, meaning that any static native data can be declared with __declspec(appdomain) and managed statics are automatically AppDomain specific. So far so good.

    Unfortunately, testing reveals that the assumption about how the AppDomains are allocated is incorrect. We have done quite a bit of research, and it seems that there is no configuration setting to make this happen.

    The questions are:

    1) We are using IIS 8 on Windows Server 2012 (because of WebSocket support). Is there some new configuration available to support this usage scenario that we have not yet found?

    2) Is there another possibility that anyone can think of for having different instances of static data on a per session basis. We are fairly close to resorting to spinning up a separate process or AppDomain as each sesson starts ourselves, but this will probably be quite a lot of work and will reduce performance as an extra marshalling/communication step will be needed, so we would like to avoid this if possible. There is also extra complexity associated with managing the processes/app domains and it feels like we are doing work that IIS is designed to do for us.

    I would be surprised if there is not a good solution to this as it must be a reasonably common usage scenario, so am hoping this is something simple we have missed.

    Thanks in advance for any ideas.

    Ian

    Monday, September 2, 2013 2:48 PM

Answers

  • Hi lan,

    According to your scenario, I'm afraid having different service instance be created on separate .NET Appdomain is not the supported behavior currently. Even if you host multiple WCF services in the same web application (in IIS), they will be loaded in the same default appdomain.

    My understanding is that you're using sessionful channel (binding) so as to make each client session have its own dedicated service instance and you want to let each service instance (per session based) have its own static data storage for storing some context data, correct?  If so, I suggest you take a look at the "instance provider" feature of WCF. You can create a custom instance provider to control the activation/creation of each service instance. Thus, you can inject your own code logic when a new service instance is created (when triggered by a new client session) so as to assiciate the instance (via some instance property) to its specific static/global data storage.

    #IInstanceProvider Interface
    http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.iinstanceprovider.aspx

    #WCF Extensibility – IInstanceProvider
    http://blogs.msdn.com/b/carlosfigueira/archive/2011/05/31/wcf-extensibility-iinstanceprovider.aspx

    #Using Instance Provider and ServiceHostFactory to Construct the Service
    http://msdn.microsoft.com/en-us/library/vstudio/hh323725(v=vs.100).aspx


    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    Wednesday, September 4, 2013 3:48 AM
    Moderator

All replies

  • Hi lan,

    According to your scenario, I'm afraid having different service instance be created on separate .NET Appdomain is not the supported behavior currently. Even if you host multiple WCF services in the same web application (in IIS), they will be loaded in the same default appdomain.

    My understanding is that you're using sessionful channel (binding) so as to make each client session have its own dedicated service instance and you want to let each service instance (per session based) have its own static data storage for storing some context data, correct?  If so, I suggest you take a look at the "instance provider" feature of WCF. You can create a custom instance provider to control the activation/creation of each service instance. Thus, you can inject your own code logic when a new service instance is created (when triggered by a new client session) so as to assiciate the instance (via some instance property) to its specific static/global data storage.

    #IInstanceProvider Interface
    http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.iinstanceprovider.aspx

    #WCF Extensibility – IInstanceProvider
    http://blogs.msdn.com/b/carlosfigueira/archive/2011/05/31/wcf-extensibility-iinstanceprovider.aspx

    #Using Instance Provider and ServiceHostFactory to Construct the Service
    http://msdn.microsoft.com/en-us/library/vstudio/hh323725(v=vs.100).aspx


    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    Wednesday, September 4, 2013 3:48 AM
    Moderator
  • Hi Steven,

    Thanks for that. I will look into that at some stage. For now, I have gone down the route of creating my own app domain as the service connects. We are passing strings and memory streams across the app domain boundary between our code and the web socket connection. These types serialize nicely out of the box, so this turns out to be fairly straight forward to derive from the MarshalByRefObject class and create using CreateInstanceAndUnwrap in the new app domain. There does not seem to be a noticible impact on performance.

    We did hit an issue with having static native data which was local to a function (declared with __declspec(appdomain)  ) that was not getting constructed in each app domain, but this was solveable by reorgainising the code so it was a class member which works as expected.

    Ian

    Wednesday, September 4, 2013 3:58 PM