MSMQ Samples

Here is a sample of  using MSMQ

The example in .NET Framework essentials does not seem to work.

This is still a simpliefied version, not actually handling timeouts very cleanly.

//This is Enque:
// Enque.cs
using System;
using System.Messaging;

namespace EnqueSample
{
    [Serializable]public struct Customer
    {
        public string Last;
        public string First;
    }
    class EnqueSample
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main(string[] args)
        {
            try
            {
                string path = “.\\PRIVATE$\\NFE_queue”;
                if (!MessageQueue.Exists(path))
                {
                    MessageQueue.Create(path);
                }

                MessageQueue q = new MessageQueue(path);

                Customer c = new Customer();
                c.Last = “Eyre”;
                c.First = “Chris”;

                q.Send(c);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }
    }
}
// Deque
// Deque.cs
using System;
using System.Messaging;

namespace Dequeue
{
    [Serializable]public struct Customer
    {
        public string Last;
        public string First;
    }
   
     class Dequeue
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main(string[] args)
        {
            try
            {
                string strQueuePath = “.\\PRIVATE$\\NFE_queue”;

                if (!MessageQueue.Exists(strQueuePath))
                {
                    throw new Exception(strQueuePath + ” does’nt exist”);
                }
                MessageQueue q = new MessageQueue(strQueuePath);

                Type[] t = {typeof(Customer)};
                ((XmlMessageFormatter)q.Formatter).TargetTypes = t;

                Message m = q.Receive(new TimeSpan(0,0,5));

                Customer c = (Customer) m.Body;

                Console.WriteLine(“Customer: {0} {1}”, c.First, c.Last);

            }
            catch(Exception e)
            {
                Console.WriteLine(e.ToString());
            }
            System.Console.ReadLine();
        }
    }
}

Second step in remoting example.

This is an extension of my earlier example.
This version makes the remote object methods virtual.
This means that the client does not actually need to know anything about the actual
type of the implement object.

Common library:
// SimpleRemoting.cs
using System;
using System.Runtime.Remoting;

// Add a reference to System.Runtime.Remoting
namespace SimpleRemotingLibrary
{
    /// <summary>
    /// This is a common object for the remoting
    /// </summary>
    public class RemoteHello  : MarshalByRefObject
    {
        static string msg = “Hello, Universe of .NET”;
        public virtual string SayHello()
        {
            Console.WriteLine(RemoteHello.msg);
            return msg;
        }   
    }
}

// Server
// HelloServer.cs

using System;

// Add a reference to System.Runtime.Remoting
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
// Add a reference to SimpleRemotingLibrary
using SimpleRemotingLibrary;

namespace SimpleServer
{

    public class RemoteServer : MarshalByRefObject
    {
        [STAThread]
        public static void Main(string[] args)
        {
            TcpChannel channel = new TcpChannel(4000);
            ChannelServices.RegisterChannel(channel);
            RemotingConfiguration.RegisterWellKnownServiceType(typeof(HelloDescendant),
                “HelloDotNet”,
                WellKnownObjectMode.Singleton);
            System.Console.WriteLine(“Hit <enter> to exit…”);
            System.Console.ReadLine();
        }
    }
    /// <summary>
    /// This is one technique where you can distribute a common base class
    /// and only implement the details in the server object.
    /// </summary>
    class HelloDescendant : RemoteHello
    {
        private static string msg = “This is a descendant”;
        public override string SayHello()
        {
            Console.WriteLine(HelloDescendant.msg);
            return msg;
        }   
    }

}

// Client – this is unchanged
//  HelloClient.cs
using System;

// Add a reference to System.Runtime.Remoting
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
// Add a reference to SimpleRemotingLibrary
using SimpleRemotingLibrary;

class RemoteClient
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main(string[] args)
    {
        try
        {
            TcpChannel channel = new TcpChannel();
            ChannelServices.RegisterChannel(channel);

            RemoteHello h = (RemoteHello) Activator.GetObject(typeof(RemoteHello),
                “tcp://127.0.0.1:4000/HelloDotNet”);
            System.Console.WriteLine( h.SayHello() );
        }
        catch(Exception e)
        {
            Console.WriteLine(e.ToString());
        }
        System.Console.ReadLine();

    }
}

Minimal Remoting sample that works in the VS.NET IDE

This is a small sample app that actually works in the VS.NET IDE.

This is in three parts:

One common library to implement the remoting object,
One server and one client.

Common library (simple library project):

// SimpleRemoting.cs

using System;
using System.Runtime.Remoting;

// Add a reference to System.Runtime.Remoting
namespace SimpleRemotingLibrary
{
    /// <summary>
    /// This is a common object for the remoting
    /// </summary>
    public class RemoteHello  : MarshalByRefObject
    {
        static string msg = “Hello, Universe of .NET”;
        public string SayHello()
        {
            Console.WriteLine(RemoteHello.msg);
            return msg;
        }   
    }
}

// HelloServer.cs

using System;

// Add a reference to System.Runtime.Remoting
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
// Add a reference to SimpleRemotingLibrary
using SimpleRemotingLibrary;

public class RemoteServer : MarshalByRefObject
{
    [STAThread]
    public static void Main(string[] args)
    {
        TcpChannel channel = new TcpChannel(4000);
        ChannelServices.RegisterChannel(channel);
        RemotingConfiguration.RegisterWellKnownServiceType(typeof(RemoteHello),
                                                            “HelloDotNet”,
                                                            WellKnownObjectMode.Singleton);
        System.Console.WriteLine(“Hit <enter> to exit…”);
        System.Console.ReadLine();
    }

}

// HelloClient.cs

using System;

// Add a reference to System.Runtime.Remoting
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
// Add a reference to SimpleRemotingLibrary
using SimpleRemotingLibrary;

class RemoteClient
{
    [STAThread]
    static void Main(string[] args)
    {
        try
        {
            TcpChannel channel = new TcpChannel();
            ChannelServices.RegisterChannel(channel);

            RemoteHello h = (RemoteHello) Activator.GetObject(typeof(RemoteHello),
                “tcp://127.0.0.1:4000/HelloDotNet”);
            System.Console.WriteLine( h.SayHello() );
        }
        catch(Exception e)
        {
            Console.WriteLine(e.ToString());
        }
        System.Console.ReadLine();

    }
}

You need to start the server first…

Dot Net Rocks Answers

I have been listening my way through the back catalog of Dot Net Rocks.
There have been some reoccouring questions:

How do I move a web service
How do I keep my code updated with respect to changes in my database structure.

There stock answers are:

You should never need to move a web service.
You should design your database up-front so it should not need to change.

These are grossly simplified. I have encountered a case where a website had to move due to legal questions about the name – the site had been located where it was for a year. Web services can and will suffer the same fate.

Database structures will change. We had to add an entire subsystem to the product that we are working on to support one line in the requirements. Change happens. The trick is to use tools that minimise that change. That can mean restricting the use of strongly typed datasets.

Guys please think about your snappy answers.

VS.NET Gotcha

I have been investigating .NET Remoting from a VS Client.
The IDE will only allow references to dll’s while the command line will allow references to exe’s.

Since the command-line tools do allow this this seems to be a pointless restriction.

1984 Returns

Have a quick look at this.

What the hell are microsoft thinking of?
Intellectual Property is the vague cover for the merging of the distinct areas of

  • Copyright
  • Patent
  • Trade Secrets

Intellectual Property Theft is a meaningless concept. The actual crime would be a Copyright/Patent/Non-Disclosure agreement violation which is not theft.

Cheap means of eliminating VB.NET

This company: elegancetech has a utility called C Sharpener for Visual Basic.
$99 dollars for a single user licence looks to be very good value.

This would be great for C# shops that have to take over maintenence of VB.NET code.

While it is great that .NET allows cross language work life is much easier if a shop sticks to one language. It would be a different matter if the two langauges were different in their expressiveness (say a functional language versus an OO one) but having two similar languages adds nothing to the mix.

I have nothing against VB.NET itself (Visual Fred), as it has finally gained the language features (inheritance, sane error handling) that Delphi has had since version 1 (10 years ago). The problem is the 3 million claimed VB (VBA) programmers. While the top few percent of those are likely to be decent devlopers the vast majority have the programming experience of  record macro then (possibly) edit. This leads to unmaintainable code. I have worked alongside professional VB developers whose idea of code reuse within a project consisted of cut-and-paste at best and the creation of reusable routines was a novelty.