Wednesday, July 16, 2008

Yield Returns and Remoting

I ran across a weird error message the other day:



System.Runtime.Serialization.SerializationException: Test method YieldSerializtionTests.Test.TestRemoting threw exception: System.Runtime.Serialization.SerializationException: Type 'YieldSerialization.RemoteObject+d__0' in Assembly 'YieldSerialization, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.



Well I looked at looked at type RemoteObject and it was marked as serializable and inherited from MarshalByRef. So that seamed fine. So what the heck is the CLR's problem? I'll let you look at the code and see if you can spot the problem.

The server:


public class Server : IDisposable
{
    private IChannel channel;
    public Server()
    {
        this.channel = new TcpChannel(Common.Port);
        ChannelServices.RegisterChannel(this.channel,false);
        RemotingConfiguration.RegisterWellKnownServiceType(typeof(RemoteObject),
            Common.ObjectName, WellKnownObjectMode.Singleton);
    }
    public void Dispose()
    {
        ChannelServices.UnregisterChannel(this.channel);
    }
}

The Client:


namespace YieldSerialization
{
    public class Client
    {
        private RemoteObject myObject;
        public Client()
        {
            this.myObject = (RemoteObject)Activator.GetObject(typeof(RemoteObject),
                string.Format("tcp://localhost:{0}/{1}",Common.Port, Common.ObjectName));
        }
 
        public int Works
        {
            get
            {
                return this.myObject.WorkingList.Count();
            }
        }
 
        public int DoesNotWork
        {
            get
            {
                return this.myObject.NonWorkingList.Count();
            }
        }
    }
}

The test:


[TestMethod()]
public void TestRemoting()
{
    using (Server s = new Server())
    {
        Client c = new Client();
        Console.WriteLine(c.Works);
        Console.WriteLine(c.DoesNotWork);
    }
}

The (outline of the) Remote Object:


[Serializable]
public class RemoteObject : MarshalByRefObject
{
    public IEnumerable<int> NonWorkingList
 
    public IEnumerable<int> WorkingList
}


One thing to note is the the call to WorkingList works fine, where as the call to NonWorkingList causes problems, but they have the same signature, how can that be? Well lets take a look at the full remote object:


[Serializable]
public class RemoteObject : MarshalByRefObject
{
    public IEnumerable<int> NonWorkingList
    {
        get
        {
            for (int i = 0; i < 10; i++)
            {
                yield return i;
            }
        }
    }
 
    public IEnumerable<int> WorkingList
    {
        get
        {
            List<int> results = new List<int>();
            for (int i = 0; i < 10; i++)
            {
                results.Add(i);
            }
            return results;
        }
    }
}


As you may have groked from the title of the article yield returns and remoting don't get along. Using the yield return generates a separate hidden class that isn't marked as serializable. The trick is that you have to provide a custom enumerator. Seams a little bogus to me, if the compiler is generating a fake class from a serializable class it should do everything if can to generate a serializable class for you.

The worst part of this is that it is only caught at runtime. If making the hidden class serializable is not feasible then the next best thing would be to error or warn at compile time. Maybe a warning when using yield returns in serializable classes?

Monday, July 14, 2008

The Business of Graves

Every day as I am coding on the train (wink) I pass a cemetery. The most interesting thing about the cemetery is the sign on the street corner making a witty remark about driving safely and not wanting your business right away. I am a big fan of witty remarks, especially in unexpected situation, like at a cemetery.



But that got me to thinking about the business of cemeteries. It seams a (very) little bit like the business of software. Once you sell your product you have to maintain it for a long time. Most business sell a product and forget about it. Some like cars, even make money on the support (what a great business, the cheaper parts you put in the more money you make on service, excluding of course your reputation. Sounds like a good post topic). But software (at least some of it) and cemeteries, not so much, you are expected to maintain your product forever unless otherwise laid out in the contract. At least with software once you make one unit, making (if not selling) the rest are free. Cemeteries get all of the same pain, but with none of the upside. Certainly there are overhead costs that apply for having only one grave site, but as we will see a lot of their costs scale with the number of units sold. So how good of business could it be?



By and large most cemeteries are not for profit (but that has been changing lately) ,this strengthened my belief that the business of burying people wasn't such a good one. So I decided to crunch the numbers. The one part of the business that interested me most is the actual plot selling and maintenance part. Everything else (casket sales, preservation services, etc...) seams like a pretty normal business, a one time service or product is provide you make your margin, and that's that.



So lets crunch the numbers for plot sales. Note, I am not an expert in any of this, all these numbers are gotten from a little googling I did, so please don't take any of this as definitive, I am just trying to ball park things. I looked at three scenarios: poor, medium, exorbitant.
Assumptions: land is free, if you are starting a cemetery you probably ain't going to buy land downtown, you are going to pick a nice scenic field somewhere where no plants grow and farmers are willing to part with for very close to nothing, at least that's what I would do.























































































PoorMediumExorbitantNotes
Price$300$2500$5000

http://www.funeralplanning101.com/burial-interment/buying-grave-plot.aspx


http://orangecounty.craigslist.org/for/742755513.html

Commission15%7.5%0%
Net Sale Price$255$2312.5$5000
Real Yield1%2%4%http://planning.tdameritrade.com/srl/tda/library_article.jsp?tid=0034&catid=000649&client=tda
Annual Real Profit Per Plot$2.55$46.25$200
Land Utilization80%65%50%The nicer need more landscaping to command the higher price
SQFT/Acre43,56043,56043,560
Sellable SQFT/Acre348482831421780
Plot Size (SQFT)272727
Plots/Acre1290.661048.66806.66
Gross Real Income Per Acre/Year
$3291.2$48500.8$161333.3
Maintenance Cost/Acre/Week$40$100$200http://www.lawnsite.com/archive/index.php/t-104651.html
http://www.post-gazette.com/regionstate/199905243deathseries1.asp
Cost/Acre/Year$2080$2621.6$4033.3
Net Income/Plot/Year$.94$41.29$187.11
Profit/Plot Sold$93.84$2064.57$4677.68
Profit Margin31%84%93.55%




So as you can see all three scenarios are profitable for the funeral home. This was pretty surprising to me. I was assuming the plot sales would be a loss leader to get people in the door and then they could make up the money with everything else. But even paying just $300 for a site is enough to still make money. Which wasn't really what I would have expected, but is pretty interesting, maybe I'll give up coding and get into the digging business. And with 90+% margins grave digging give software a run for its money.