Ayende @ Rahien

It's a girl

Rhino Mocks 2.8.1

Well, it looks like I’m back to making daily releases of Rhino Mocks. Royston Shufflebotham has been bombarding me with patches, this new releases contains:

  • A lot more overloads for multi mocks, including the ability to use multi mocks with partial mocks and being able to creates multi mocks with constructor arguments.
  • Can now call CallOriginalMethod() from LastCall as well as Expect.
  • A way to disambiguate between properties with the same name from different interfaces with constraints.
  • Some better debug information for those of us who debug Rhino Mocks.

A big thanks to Royston, who has been doing a lot lately to give Rhino Mocks even more great capabilities. Source and binaries are in the usual place.

Published at

Rhino Mocks Tidbits

About ten months ago I managed to put Rhino Mocks (version 2.3.3) at 100% testability. That was the last time that I checked this, and since them I had many releases.

I checked it today, out of curiosity if nothing else, and I was surprised to discover that I still got an absurdly high level of tested code, 95% of Rhino Mocks are tested. The rest of the 5% are utility methods and the like, which I’m not going to worry much about.

The last change I did involved changing the way Rhino Mocks created mocks. This is about as important a change as you can make. This amount of testing gives me the ability to make a significant change to Rhino Mocks and still be certain that I am not breaking anything when I do it.

Published at

Breaking Changes – How?

I need to make a radical change to an application. This change is basically ripping apart a major piece of the infrastructure and replacing it with another piece, which has a different API, usage and capabilities.

I’m currently thinking about how I should do it. I got tests for the code, of course, but I don’t know how I can move it to the other infrastructure with the tests intact. My worry is that I can make the move, and then break each and every tests that relies on the infrastructure to exists (~140 tests, I think). This is a big problem because I will need to change both tests and code just in order to get the code to compile again.

I’m not going to remove the tests, since they test functionality that is needed for the application, so at the end of the conversion, I know that I am at the same point that I was before I started all of this.

If anyone has any ideas, I would love to hear them.

Published at

Evaluating Enterprise Library 2.0

Because, I didn’t have an inflammatory post in nearly two days, and I’m feeling faint

Anyway, I’m working at the moment at a highly Microsoft focused client. Which means that they consider the Enterprise library as Mana From Heaven. This forced me to raise from my own pile of tools and take a look at the Enterprise Library.

I can’t say that I am overly impressed. Here is my quick summary:

Name

Opinion

Configuration

Not sure why we will need this now. There are strongly typed accessors for configuration, and they are flexible enough to do whatever I need. If I need to pull the configuration out of the database, I can do this in one line of code (using Active Record).

If I need to do complex configuration, including object graphs, I will either use a data base and Active Record, which make it a breeze, XML Serialization or just rethink what I’m trying to do.

For me, all those lengthy configuration files are death-by-XML.

Instrumentation

They mention event log, performance counters and WMI events. I’m not sure why the event log is in instrumentation, and I’m clueless with regard to WMI events, but why do we need another layer on top of performance counters?

I just did a project that required some heavy use of performance counters, and the API couldn’t really be simpler.

Object Builder

There is something very wrong in Microsoft building their own IoC container.

The Object Builder looks like a reasonable implementation of Dependency Injection and Inversion of Control container, but I don’t see any reason to use it except that it got “Microsoft” in its name.

Logging

Again, I have a problem with this, mainly because of log4net. It was there first, after all. Why do the same thing again?

Data Access

I got NHibernate, enough said

This looks like a whole lot of work to get what I have seen Oren Ellenbogen do in about five minutes and 15 LoC using delegates.

Exception Management

This one I like in concept, but not in practice. The problem that I have with this is code such as this: “if(ExceptionPolicy.HandleException(ex,”Foo”)) throw;” This presume that under some circumstance I will want to swallow an exception. This kind of stuff gives me ticks. You have no idea how big a bug-fest can get when such a thing is happening. Errors are vanished into the night, and so is sanity, soon after.

What is interesting about the exception handling is that it supposed to prevent you from leaking sensitive data to remote callers on error conditions. It is a notable goal, I just got a design problem with solving the problem this way.

Depending on the application, I would either hook an OnError event (ASP.Net) or provide a service decorator that handles this (web services / Remoting).

Beyond that, I suspect everything that has boilerplate code in it.

The real problem is that all the things that it is trying to achieve are not something that could change safely without affecting all calling code.

Caching

This one looks cool. A durable cache that survives application restarts is something very interesting. Of the top of my head, the only kind of applications that I would use this is for partially connected applications, like smart clients, etc. A cache is something that takes care & feeding, not something that you can just use without thinking about.

(Cache invalidation policies, for instance. Concurrency issues, etc. )

I would generally not bother with those issues unless I had a partially connectivity scenarios.

Cryptography

Um, why? None of the services that they offer can’t already be had from the framework in five lines of code tops.

Security

It looks nice, but I don’t know enough on the subject to talk.

 

One thing that annoys me about the Enterprise Library is that at least two of the core components are duplication of outside effort. I can think of at least two well known logging framework for .Net (log4net & NLog ), both of which existed before the Logging Application Block saw the light of day. I can’t think of all the IoC containers for .Net, and that is because there are so many of them.

I got an issue with this because it creates an artificial segmentation of the tools. As far as I can say, those tools were not created because of some need that Microsoft could not meet using the open source equivalents. Nor because of some licensing issues (like NAnt / MSBuild) since most of the IoC containers for .Net as well as log4net are free for the taking. Including for commercial use.

Published at

Rhino Mocks 2.8 Released – Multi Mocks

I said it before, but I just have to say it again. It is a big mistake to release software. Any time that I do it, I need to make a new release soon after. (And no, not a bug fix release {usually} ).

Yet I did make the mistake of releasing the most dangerous software of them all, Rhino Mocks. The moment I do something to this beast, a new feature request come up. The problem is that I’m a sucker for frequent releases, I just can’t help implement features and ship them.

This release brings one major feature to the table, Multi Mocks. What is a Multi Mock?

A Multi Mock is a mock object that implements several interfaces. For instance, you may want to test this code:

public void CleanCollection(CollectionBase collection)

{

collection.Clear();

IDisposable disposable = collection as IDisposable;

if(disposable!=null)

disposable.Dispose();

}

 

As you can see, we accept a collection, and we make sure to dispose of it if it is disposable. CollectionBase does not implements IDisposable, so this would usually force us to create a dummy class to make the MockRepository think that we need all those interfaces.

Instead, we can now do this:

[Test]

public void ClearCollectionAndDisposesIt()

{

MockRepository mocks = new MockRepository();

CollectionBase collection = (CollectionBase)mocks.CreateMultiMock(        typeof (CollectionBase), typeof (IDisposable));

collection.Clear();

((IDisposable)collection).Dispose();

 

mocks.ReplayAll();

CleanCollection(collection);

mocks.VerifyAll();

}

 

There is also a DynamicMultiMock, with the same behavior. The functionality exists with generic overloads for 2.0, of course. Oh, I also added AtLeastOnce to the default options for repeating. I was asked to do this a long time ago, and I just forgot.

You can read the feature request here. This is also very useful in Remoting scenarios.

By my calculations, it is less than 6 hours from the feature request to shipping a well tested version out the door. Take that, Test Driven Development naysayers! As usual, you can get both binaries and source here.

Thanks against for Royston Shufflebotham for presenting such a clear need.

Tags:

Published at

NHibernate and XML Column Types

One of the reason that I like NHibernate so much is that it is so extensible. It took me about half an hour to allow NHibernate to understand that an XML column is a XmlDocument, and I didn’t have to use any tricks. It was very easy to do, which says quite a lot about NHibernate. Less than 30 lines of code, at the end.

The nice thing is that I am not limited to converting Xml to XmlDocument, I can very well use Xml Serialization for objects, and store them as XML in the database. There are some scenarios where this is useful, like extended properties, etc.

The scary thing is that I can feel someone in the back of my head implementing the architecture for a full blown IoC framework on top of this ability and SQL Server’ XML column type.

I put the code here.

Published at

NHibernate Generics 1.0.9

Okay, this release is to make a small fix that affected only people who were using NHibernate Generics and web services.

I’m not sure what the problem was, but I’m pretty sure that I fixed it.

If you got an error like “You must implement a default accessor on EntitySet<> because it

inherits from ICollection.”, you probably want to give it a try.

Source and binaries are here, as usual. There is a download already, and I just put it up there and in the process of writing this post, so hurry up before it runs out.

 

The Future of NHibernate.Generics

NHibernate.Generics was meant to provide a way to use generics with NHibernate, and along the way I put some smarts into the collections, which allows me to relax with regard to maintaining references between associated objects.

Now, NHibernate has a 1.2 alpha release that include generics, as well as some extensions to the collection model, which will make the work of integrating with NHibernate easier.

At the moment, I’m not sure about the status of NHibernate.Generics when version 1.2 of NHibernate is released. It is probable that I will modify the library in a breaking manner in order to make it work better with the new release. Not sure about anything yet, of course.

Published at

So, what is up with the name?

Some people are confused by the nickname that I use on the web, and I thought that I would explain what it is all about.

About six or seven years ago, I was really big Wheel of Time fan (and still am). The name Ayende Rahien comes from this series. The literal translation is “dawn of freedom”. Yes, it is silly, but in my defense, I was seventeen . I used the nickname for all my online activities, up to and including my computer’s username.

Fast forward to the beginning 2004, I was using the name Ayende Rahien so long that it became automatic. When I opened a site, it was natural to use this name. Another reason was that at the time I was at the army, and I didn’t know (nor do I know now) what is the army’s stance with regard to blogging. I know of at least one case of a soldier getting into trouble for posting a review about a TV Show in his blog.

At the moment, I got another reason to use this name. Ayende is not common, Oren is. I got a friend who tells me that there are four Oren in his team. I once checked, and at Israel alone, there are over 8,000 people with this name. There are also six or seven guys named “Oren Eini”.

The end result is that searching for Ayende will bring you to my blog, which is not something that I have been able to do had I been using my real name, which is far too common.

Published at

Rhino Mocks 2.7.2

I just got a really nice patch for Rhino Mocks from Royston Shufflebotham, which include the following new constraints:

Is.Same() constraint, when you need to do reference equality and not just equality.

Property.ValueConstraint() which allows you to specify constraints on a property value, like this:Property.Value( "X", 5 ) & Property.ValueConstraint( "Y", Text.Contains( "foo" )&!Text.Contains("bar"))

The nice thing about it is that you can chain Propety.ValueConstraint() to check an object two level deep (or more, of course).

I would like to thank to Royston for the patch, it was very well done.

As usual, you can get the source and binaries here.

Published at

Outlook’ RSS not so good

Here is an interesting observation. In most products that I beta test, there is usually Help > Report Bug / Send Feedback right there in the application.

For Microsoft applications, there never seem to be such an easy way to report bugs. And here I thought that the purpose of betas was to find bugs. I got at least three right now that I am not going to go out of my way to report because it is too hard.

After the annoyances that I detailed before, I made a concentrated effort to use Outlook at my RSS Reader, but I just don’t see it happening.

There seem to be a lot of annoying bugs there, and not a lot to suggest that it is worth taking the time to adjust. One really annoying bug is that there is no way to centrally manage all the feeds in outlook. This means, I can click this, that and that and delete them.

I had to manually delete 300 feeds. I got too many feeds that start with “T”, I can tell you that.

Published at

Paul Wilson On OR/M vs. SP

In an exceptionally written post, Paul Wilson drives at least a couple of wedges into the OR/M vs. SP arguments. Perhaps it is good that we are having the same conversation every four months or so, so far there have been at least a couple of new points brought up that I haven’t seen before.

The most interesting part in Paul’s post was when he talks about SP for security in the face of connection pooling. Since most application will use a single connection string to access the database, in order to utilize connection pooling, the security provided by stored procedures is meaningless. All the users of the applications map to the same user in the database. All with the same permissions.

Published at

Looking for “Add To Path” UI

I’m working with the command line a lot, and I got a lot of different directories in my path. The problem is that I having to edit the path variable in the measly UI in the computer properties sucks.

Is there a good UI for this? A shell extension or an editor?

Published at

NHibernate Query Analyzer 1.1.5

There is a new release out. This one add object graph support for simple types (results from “select count(*) from Foo”) and for imported classes (results from “select new DictionaryEntry(id,name) from Foo”).

As usual, both source and binaries for .Net 1.1 and 2.0 are available here.

Published at

How to enable posting from Word 2007 to dasBlog

Apparently, there is a compatibility issue between Word 2007 and dasBlog 1.8.5223.0 (my version). I fixed it by getting the source from their (http://www.xml-rpc.net/), recompiling it, and then uploading it to the server.

For some reason dasBlog uses an unsigned version of the xml-rpc library, which meant that a mere binding redirect would not work (can’t change public keys this way). Since I was already compiling it, I also changed the version number to match the one that dasBlog is expecting, this saved the need to do a binding redirect.

If anyone else is interested with the file, ping me.

Published at

How to build an mission critical system

The most mission critical system that I built was one to handle sentences calculations for my prison. The result of a failure in the system would mean that either a terrorist would walk away, or that an innocent guy will be in jail for no reason.

In both scenario, yours truly would have found himself taking a trip to the other side of the bars.

That is pretty mission critical, I say. Any software that can land me in jail is mission critical in my book, anyway.

The problem that I was never a developer in the army, so I had a really locked down computer, with no way to do anything to it (no USB, Floppy, CD, etc), the network was heavily monitored, etc.

That left me with a basic windows + office setup, to create my system. I put some thought into, and then wrote the whole thing in Excel and VBScript. It does reporting, calculations, warning, and whatnot. A scheduled task or two later, and I had scheduled report to HQ as well.

I has been two years since I had written this “system”, and it is still in use today. In fact, it got passed around to other prisons who are using it as well.

It is Excel, and the code there stinks (17 types of different warrants, and no OO for inheritance, welcome to the big CASE statement), but it actually never had a bug. Scary.

Published at

Outlook 12 RSS Support

I wonder if I’m unique in my syndication needs. At the moment, I can’t really think of any one site that I regularly visit unless it has an RSS Feed and I want to see the comments.

I decided to import my 300 feeds list into outlook 12, and see how it handles it. There doesn’t seem to be problem with the size of the feed list, but I have several problems with the way the UI is handled compared to my favorite RSS Reader, RSS Bandit.

1.       It ignores categories. I’ll be the first to admit that my category list sucks (I got Australian bloggers in the Israel category, for instance), but it makes sense to me, and I have grown fond of it.

2.       There is no easy way to get a number of how many unread posts I have.

3.       There is no easy way to go through all the feeds from one feed to the other using the keyboard.

4.       It shows an image holder with some icon in it, which is bad since many aggregators are using 1x1 gifs to track readership. It is annoying to see the image and then have it disappear.

5.       No way to click on a feed and select Update.

6.       For some reason is show all the posts in my feed twice. It may be just the first time, but I’ll have to see

 

When I am reading blogs, I usually have to read about 80 – 120 posts, about 85% of them are full of technical content that can be hard to follow. About half the time I would think that the material is interesting but not relevant to what I do at the moment, make a note of it (in my head, not on paper or computer) and move to the next item.

This mean that such thing as clicking on a feed, scanning all the posts, and moving on is very important to me (newspaper style). I don’t see support for this in Outlook, which is a shame.

At the moment, I defined a search filter that bring me all the unread items from the RSS Feeds folder. With some custom grouping, I can get a very good sense of what is going on, and I can move between posts by pressing space. I guess that I can also do full screen viewing of posts and move between them (which would be cool).

Published at

Impressed by Outlook 12 Setup

Okay, so I got around to setup Outlook 12 with my pop3 mail, and I give it my name and email, and click next. It spent some time thinking, and then it configured itself on its own. As someone who has gone through countless of those setups, this is very cool.

Since the server configuration is mostly standardized, it is easy to see how they do it, I even read somewhere that they give the server a way to hint to Outlook what the settings are.

It is easy of the surface (I'm sure that there are many pitfalls under the cover) and it is very sweet.

 

Published at

A Cool Aspect Of Integration

While it looks like the MS products integration has hurt their agility, I like the results of this.

This mean that I can copy & paste class diagrams from VS to any Office product, this is very cool, and I had a thrill of excitement realizing that this works. I didn't consider that it might work, so previously I did using PrtScrn and Paint.

Published at

Making The Wheel Round

Two days ago I posted about a nasty piece of code that I had to decipher.  The code was very simple to look at, just take the information in the transaction table and update the customers with the current transactions summary.

What everyone who commented (and me as well) missed is that this method is doing a bit more than just update the customers table with the transactions. It also zeros the transaction count / sum if the customer has no transactions!!!

I played with the code for hours before it came up to me.

I am pretty sure that this is an unintended side affect, but I had to duplicate it as well (not hard once I knew what the difference was).

The problem? The SP (the code I gave is in C#, because I refuse to write cursors on my spare time) run in Oracle, which has such a fabulous support for debugging, and a fantastic error reporting capabilities ("Procedure saved with errors." What errors? Oracle knows, but he wants me to pay before he will tell me. ARGH!)

 

The procedure run for three hours under  oracle using the cursor based logic, when I finally got the SQL version to work, it run for 22 seconds, and I know that I'm being inefficient there.

Published at

Advanced Uses For OR/M

There is another holy war converging about the SP vs. Parameterized SQL  topic. I got into one not long ago, and I wouldn't get into this one if there wasn't some new stuff brewing in it.

Eric Wise started this with a The Pragmatic Adhoc SQL vs Stored Procedures Discussion, Jeremy D. Miller responded with Why I do not use Stored Procedures and then Eric posted a new post, this time with In Response To No Stored Procedures which has some new questions that I have not seen before.

1.       About the security, naturally, security is a multi layered approach. In the database, I would grant permissions to views or tables according to the user's need. Granting a SELECT permissions does not equals to letting the user SA access to the database, after all. I also tend to add another layer in the application level, which is completely transparent to my code and my business objects, you can see a high level overview here. Then there is the application logic itself.

2.  Transactional  Database Structures : A good coverage of the topic can be found in Roy 's What payroll system are a pain to design – Temporal data  and in Eric's "Transactional" Database Structures.  I am currently working on a big payroll system which is using NHibernate, and this issue is a major PITA. The problem is that both the relations between objects and the objects themselves are changed as time goes by.  We solved this issue by deciding that each object is the system is composed of Id, which cannot be changed, and a history, which contains immutable version of the data for a specific date. A highly simplified version of this will look like this:

This way, I can ask any object for a view of how it was in a point in time. The views also handle the associations, so if I ask an employee to see its view in 2000-12-31, I can easily get any data that I need without dealing with the complex timed model. For instance, if I want to check if the employee had a  car in a certain date, I can use this code:

EmployeeView employeeView = emp.For(new DateTime(2000,12,31));

if(employeeView.BenefitPackage.HasCar)

    Console.WriteLine("The employee {0} had a car in {1}",
                    employeeView.Name, employeeView.Date);


This model translate very well into something NHibernate can handle. It reduce a lot of the problem that you have when you deal with such system, since  the infrastructure code remove a lot of the  problems that you get in such models. To set a new property, I ask the employee to give me its current status, change whatever I want, and then I give it back and saves. A new record is inserted to the database, and the employee's current state moves to the newest piece of data.

3.       OR/M in complex databases structures. The system above gets its schema from a main frame 30 years old or more, written by a bunch of guys that thought that transliteration Hebrew in English is fun (with spelling mistakes!). Enough said, I think.

4.       Stored Procedures makes TDD slower. The problem with SP and  TDD is that you don't get any seam to verify the expected behavior. I may have  a procedure that takes a long time to run, and I need to call it from another procedure that eventually calls that procedure, I'm in more than a bit of a bind. I can replace the long running procedure on the fly, and spend the rest of my life running from angry DBAs, but that about all I can do. There is no way to put mocks in the database. And database access takes time. Often a lot of time.

 

 

 

Note about security: If an attacker is in the position where he can run arbitrary code in your system, you are screwed no matter what. OR/M, ADO.Net or SP, he can make the appropriate calls to do whatever he wants.

 

Oh, and unrelated tidbit, in the last six months I wrote over 600 stored procedures (data warehousing project), so I feel confident that I know my stored procedures.

NHibernate Generics Update

The release (1.0.8) fixes a… strange… design decision that I made, to force the field type (and not the field value) to implement a specific interface.

Now you can define your fields as ICollection<T> and it will work as long as the value is EntitySet / EntityList / EntityDictionary etc.

 

Published at

NHibernate Support

Did you know that JBoss is now offering NHibernate support? It came up during several of my recent projects, along with my life expectancy . ("What happen if you get hit by a 747* ? ")

I talked with a couple of the guys there, and they were very nice and professional. That they can purchase support seem to have eased some of the fears of going with a non Microsoft route considerably.

 

* That was after I assured them that I'll survive getting hit by a bus J

Published at

We! are hiring

Okay, this is a lame title, but my company (We!) is now hiring developers.

You can check out about the company here.

If you are a developer in Israel*, and you can follow the code that I usually post here, we will want you J

Give me a call at: 052-548-6969 or email me (orene J we-can.co.il).

 

By the way, this offer is not timed limited, if you see this post half a year from now, do give me a call. We always need good people.

 Some updates to this message:

Yes, unfortuntely we don't have a english site.

The main requirement is that you will be a good developer and like what you do.
Prior knowledge is certain technologies helps, but not mandatory. If you are good, you can learn.

That said, a passionate kid that show up with a burning desire to learn and some knowledge in Pascal that he got in high school will probably not be accepted.

We are a Microsoft shop, and nearly all development is done in .Net (C#). We are doing projects ranging from data warehousing to enterprise applications to backend components. (BTW, if you are a good VB programmer, we will welcome you in.)

If you are a regular reader of my Blog, you probably fit (if you weren't you would have stopped reading :-) ).

Just a tidbit, when I was hired, I never used SQL Server . And I currently in charge of data access implementations in several projects (all of which are using SQL Server).

* If you want to work with us from outside of Israel, give me a call, and I'll see what I can do.

Published at

The Wheel, slightly eliptic

A similar piece of code ( in PL/SQL and cursors ) kept me busy for most of the day. I have translated it to C# because I really don't think that I could stand seeing another cursor today.

Figure out what it does (it is tricky). And see if you can suggest an improvement. Both SQL and C#/ VB/ C++ (whatever) are accepted.

public void You_Commited_Grave_Sin_In_A_Past_Life_And_Are_Now_Being_Punished()

{

    SqlConenction connection = new SqlConnection(connectionString);

    SqlCommand parentCommand = new SqlCommand(connection,

        "SELECT customerid FROM Customers WHERE Active = 1");

    IDataReader parent = parentCommand.ExecuteReader();

    while(parent.MoveNext())

    {

        int custId = parent.GetInt32(0);

        int myCounter = 0;

        int myAmount = 0;

 

        SqlCommand childCommand = new SqlCommand(connection,

            "SELECT amount FROM Transactions WHERE customerID = "+custId);

       

        IDataReader child = childCommand.ExecuteReader();

        while (child.MoveNext())

        {

            myCounter = myCounter + 1;

            myAmount = myAmount + child.GetInt32(0);

        }

        parentCommand.CommandText = "Update Customers SET TransactionsCount = " +
            myCounter +
", TransactionAmount = " + myAmount + " WHERE CustomerID = "
           
+ custId;

        parentCommand.ExecuteNonQuery();

    }

}

This piece of code is reponsible for me feeling like a tank has pass through me, several times. I'm so tired I can barely think.

When you fomulate plans of action, please remember that any plan involving any of the following will not be considered (Blunt instruments, Sharp instruments, guns, maces and atomic sumbarines).



Update: Fixed tyop in code

Don't be afraid to create objects

The question came up today, how expensive it is to create objects in .Net, and is it worth keeping them in the cache if we can just as easily reconstruct them?

I wrote  a tiny program (attached) to check this issue. This program merely construct an employee instance using a typical constructor which accept the object's initial values.

The code is shown below, but I wanted to talk about the results first:

 

The times here are in minutes : seconds . milliseconds . Each point in the graph is greater than the previous one by one hundred thousand objects. As you can see, to create 5,000,000 objects it takes less the two and a half seconds.

So I wouldn't particularly worry  about instantiating objects (this doesn't include objects that holds scarce resources , like database connections, of course).

The overall test create 127,500,000 objects and took less than 1 minutes and 9 seconds.

 

Here is the code. It is ugly, but it does the job.

 

class Program

{

    public class Employee

    {

        string name, lastName, email;

        DateTime birthDay;

        int age;

 

        public Employee(string name, string lastName, string email, DateTime birthDay, int age)

        {

            this.name = name;

            this.lastName = lastName;

            this.email = email;

            this.birthDay = birthDay;

            this.age = age;

        }

 

        public string Name

        {

            get { return name; }

            set { name = value; }

        }

 

        public string LastName

        {

            get { return lastName; }

            set { lastName = value; }

        }

 

        public string Email

        {

            get { return email; }

            set { email = value; }

        }

 

        public DateTime BirthDay

        {

            get { return birthDay; }

            set { birthDay = value; }

        }

 

        public int Age

        {

            get { return age; }

            set { age = value; }

        }

    }

 

    static void Main(string[] args)

    {

        ((Action<int>) Foo).BeginInvoke(1, null,null);

        Console.ReadKey();

    }

 

    private static void Foo(int ignored)

    {

        string[] names = { "Foo", "Bar" };

        string[] surnames = { "foo", "bar" };

        DateTime[] dates = { DateTime.MaxValue, DateTime.MinValue };

        string[] emails = { "E@f.com", "Bar@asdd.com" };

        int[] ages = { 1, 23 };

 

        StreamWriter text = File.CreateText("log.txt");

 

        for (int multiply = 0; multiply < 1000; multiply++)

        {

 

            List<Employee> emps = new List<Employee>();

 

            DateTime start = DateTime.Now;

 

            int max = 100000 * multiply;

            for (int i = 0; i < max; i++)

            {

                Employee emp = new Employee(names[i % 2],

                                            surnames[i % 2],

                                            emails[i % 2],

                                            dates[i % 2],

                                            ages[i % 2]);

                emps.Add(emp);

                if (i == 5000)

                    emps.Clear();

            }

            string format = string.Format("{0}\t{1}", max, DateTime.Now - start);

            text.WriteLine(format);

            Console.WriteLine(format);

        }

 

        Console.WriteLine("Done");

    }

}

 

Published at