0

I have an ASP.net project which involves using a custom IHttpModule. This module will sit in the pipeline and when certain criteria match up, it should invoke a method on a WCF service hosted in a simple C# console application on the same machine.

The code for the module is below:

using System;
using System.Collections.Generic;
using System.Text;
using System.Web.SessionState;
using System.Web;
using System.Diagnostics;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Configuration;
using System.ServiceModel;
using SimpleFarmStateServer;

namespace SimpleFarm
{
    public class SimpleFarmModuleSS : IHttpModule, IRequiresSessionState
    {
        protected string cache_directory = "";

        // WCF
        ChannelFactory<IStateServer> factory;
        IStateServer channel;

        public void Dispose() { }

        public void Init(System.Web.HttpApplication context)
        {            
            context.PreRequestHandlerExecute += new EventHandler(context_PreRequestHandlerExecute);

            setupFactory();
        }

        void setupFactory()
        {
            factory = new ChannelFactory<IStateServer>(
                    new NetNamedPipeBinding(),
                    "net.pipe://localhost/StateServer");
        }

        void context_PreRequestHandlerExecute(object sender, EventArgs e)
        {
            try
            {
                if (factory.State != CommunicationState.Opened)
                    setupFactory();

                channel = factory.CreateChannel();
                channel.LogAccess("Hello World!");
            }
            catch (Exception ex)
            {

            }
            finally
            {
                factory.Close();
            }
        }        
    }
}

My problem is that this runs the first time, but then subsequent attempts cause this error message

The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state.

It seems as if I am doing something wrong, and I am new to WCF in general so this is very likely.

I think the issue is surrounding the ChannelFactory being recreated, and this causes the faulted state.

Mat
  • 202,337
  • 40
  • 393
  • 406
justacodemonkey
  • 620
  • 1
  • 8
  • 20

1 Answers1

1

The specific error probably means the factory faulted, threw an exception (which you're swallowing) and then when the finally block executes, the factory.Close() call fails because the factory is faulted (if a WCF object is faulted, you need to call Abort() on it, not Close()).

tomasr
  • 13,683
  • 3
  • 38
  • 30
  • This helped remove the main issue. Thanks tomasr. Now my issue is slightly different in that for each different page within the site, when it is called, a new HTTPModule instance is created. This new instance cannot connect to the named pipe due to "Only one usage of each socket address (protocol/network address/port) is normally permitted" exception - which is because another instance is connected. – justacodemonkey Feb 01 '11 at 17:39
  • HttpModules always use multiple instances. Also, note you're leaking the client channel; you're only closing the factory, not the channel (you should probably cache the factory, depending on your needs) – tomasr Feb 01 '11 at 18:56
  • Any ideas on how to cache the factory in my scenario? – justacodemonkey Feb 08 '11 at 20:39
  • Unless I needed something more special, I'd probably just implement my own client deriving from ClientBase, as it already has factory caching built-in in 3.5sp1 and up. It's the easiest option. – tomasr Feb 08 '11 at 22:05