0

I have the following WCF server and client code which I changed a bit from their [original form] (http://tech.pro/tutorial/855/wcf-tutorial-basic-interprocess-communication).

Server:

using System;
using System.ServiceModel;

namespace WCFServer
{
    [ServiceContract]
    public interface IStringReverser
    {
        [OperationContract]
        bool ReverseString(string value, out string reversed);
    }

    public class StringReverser : IStringReverser
    {
        public bool ReverseString(string value, out string reversed)
        {
            char[] retVal = value.ToCharArray();
            int idx = 0;
            for (int i = value.Length - 1; i >= 0; i--)
                retVal[idx++] = value[i];

            reversed = new string(retVal);
            return true;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            using (var host = new ServiceHost(typeof(StringReverser), new[]{new Uri("net.pipe://localhost")}))
            {
                host.AddServiceEndpoint(typeof(IStringReverser),
                  new NetNamedPipeBinding(),
                  "PipeReverse" + args[0]);

                host.Open();
                while (true)
                {
                }
            }
        }
    }
}

Client:

using System;
using System.Diagnostics;
using System.Globalization;
using System.ServiceModel;

namespace WCFClient
{
    [ServiceContract]
    public interface IStringReverser
    {
        [OperationContract]
        bool ReverseString(string value, out string reversed);
    }

    class Program
    {
        static void Main()
        {
            var currentThreadIdStr = System.Threading.Thread.CurrentThread.ManagedThreadId.ToString(CultureInfo.InvariantCulture);

            // Start off the service
            Process server = new Process();
            server.StartInfo.FileName = "WCFServer.exe";
            server.StartInfo.Arguments = currentThreadIdStr;
            server.StartInfo.UseShellExecute = false;
            server.Start();

            // Try to connect to the server
            ChannelFactory<IStringReverser> pipeFactory =
              new ChannelFactory<IStringReverser>(
                new NetNamedPipeBinding(),
                new EndpointAddress(
                  "net.pipe://localhost/PipeReverse" + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString(CultureInfo.InvariantCulture)));

            IStringReverser pipeProxy =
              pipeFactory.CreateChannel();

            Console.WriteLine("type \"quit\" to exit\n");

            string str;
            string reversedString;
            while ( (str = Console.ReadLine()) != "quit")
            {
                bool wasReversedSuccesfully = pipeProxy.ReverseString(str, out reversedString);
                Console.WriteLine("pipe: Succesful: " + wasReversedSuccesfully + "  reverse of " + str + " is:" + reversedString);
            }

            //// Kill the service
            server.Kill();
        }
    }
}

My question is:

Is there any better way of ending the server from the client code? Is there any flaw or problem with the way I am killing it in above?

Thanks!

jambodev
  • 351
  • 2
  • 3
  • 9
  • why do you want to kill the service? Also you are assuming the service and the client will work on the same machine? – daryal Feb 13 '13 at 13:39
  • yes they are supposed to work on the same machine. – jambodev Feb 13 '13 at 13:40
  • Are you just creating an exercise in named pipes? I don't get why you would create a service that is started by a program and then stopped by the same program... – Brian P Feb 13 '13 at 13:43
  • OK, let me explain a bit more as to why I am doing this: what I am going to put in the service, is not thread-safe, the client program, is part of a fully thread safe framework. I am doing this as the framework (on each running thread) is supposed to create the service as a separate process and get the result back from it, and this (i.e. need to call to service) can happen for each thread on a non-deterministic number of times. erm, I might be wrong killing the service ? – jambodev Feb 13 '13 at 13:50

1 Answers1

2

Based on the comments you have provided, instead of killing service instance directly; you may just mark your service InstanceContextMode=PerCall and ConcurrencyMode=Multiple. This way, for every request a new instance will be created and this instance will run on a thread assigned by WCF host.

Beware that, during execution, the thread on which operation is being executed may change.

daryal
  • 14,643
  • 4
  • 38
  • 54
  • erm, shouldn't I use 'InstanceContextMode=Single' and 'ConcurrencyMode = ConcurrencyMode.Single' ?? – jambodev Feb 13 '13 at 15:11
  • I now understand that if I have a global service I need `InstanceContextMode=PerCall ` and `ConcurrencyMode=Multiple`, Thanks for that. but If for some technical reasons (where threads are being created, I don't have enough information as to which type of service I am going to create, I only have this information when I am already in a running thread), I ended up creating one service per thread, then I need: `InstanceContextMode=PerCall ` and `ConcurrencyMode=Single`, am I right ? – jambodev Feb 13 '13 at 15:51