Category Archives: c#

Quartz – scheduling tasks in C#

Quartz is a scheduling library. You can run your task periodically.
This is how scheduler and it’s triggers can be configured.

        private static void ConfigureScheduler()
        {
            var scheduler = new StdSchedulerFactory().GetScheduler();
            var job = JobBuilder.Create<PrintDateTimeJob>()
                .WithIdentity("MyJob")
                .Build();

            var trigger = TriggerBuilder.Create()
                .StartAt(new DateTimeOffset(2000, 1, 1, 10, 0, 0, TimeSpan.FromSeconds(0)))
                .WithSimpleSchedule(x => x.WithIntervalInSeconds(5).RepeatForever())
                .WithIdentity("MyTrigger")
                .Build();

            scheduler.ScheduleJob(job, trigger);

            scheduler.Start();
        }

Your task class must implement IJob interface.

    class PrintDateTimeJob : IJob
    {
        public void Execute(IJobExecutionContext context)
        {
            Console.WriteLine("Current date and time: " + DateTime.Now.ToLongTimeString());
        }
    }

Code above will schedule simple job (printing current time) every 5 seconds. This is a simple example only. For detailed information go to: Quartz.NET.

Advertisements

C# – XML Serialization

This exaple shows how to serialize class to XML. XmlSerializer is used. Notice how attributes are used to avoid exceptions and format the output file.

namespace SimpleExamples
{
    static class SerializationIssue
    {
        public static void Serialize()
        {
            var config = new Config();
            config.Person1 = new People.Mx.Person() { Name = "John", BirthYear = 2000, Profession="SalesManager" };
            config.Person2 = new People.Ax.Person() { Name = "Adam", BirthYear = 1950, Profession="SoftwareDeveloper" };

            var path = Path.GetTempFileName();
            using (var s = new FileStream(path, FileMode.Create))
            {
                new XmlSerializer(typeof(Config)).Serialize(s, config);

                Console.WriteLine(s.Length);
                Process.Start(path);
            }

            var reader = File.OpenRead(path);
            var deserializedConfig = new XmlSerializer(typeof(Config)).Deserialize(reader) as Config;
        }
    }

    [Serializable]
    //sets namespace and name of the root element
    [XmlRoot(ElementName ="Configuration", Namespace ="Configurations")] 
    public class Config
    {
        [XmlElement(ElementName ="PersonA")] //sets the name of Person1 element
        public People.Mx.Person Person1 { get; set; }

        [XmlElement(ElementName ="PersonB")] //sets the name of Person1 element
        public People.Ax.Person Person2 { get; set; }

        [XmlIgnore] //this element won't be serialized
        public int X { get; set; }
    }
}

namespace People.Mx
{
    [Serializable]
    //allows to serialize many classes with the same name but in different namespaces
    //without this attribute on both Person classes exception is thrown during serialization
    [XmlType(TypeName = "Prsn1")] 
    public class Person : PersonBase
    {
        public string Profession { get; set; }
    }
}

namespace People.Ax
{
    [Serializable]
    //allows to serialize many classes with the same name but in different namespaces
    //without this attribute on both Person classes 
    //exception is thrown during serialization[XmlType(TypeName = "Prsn1")] 
    [XmlType(TypeName = "Prsn2")]
    public class Person : PersonBase
    {
        public string Profession { get; set; }
    }
}

namespace People.Base
{
    public class PersonBase
    {
        public string Name { get; set; }
        public int BirthYear { get; set; }
    }
}

For more about Equals method see:
https://msdn.microsoft.com/en-us/library/182eeyhh(v=vs.110).aspx
https://msdn.microsoft.com/en-us/library/58a18dwa(v=vs.110).aspx
https://msdn.microsoft.com/en-us/library/2baksw0z(v=vs.110).aspx

C# – Equals() and GetHashCode()

GetHashCode and Equals methods are used to compare objects i.e. when they are inserted into dictionary.
At first GetHashCode is invoked. When object hash code is not colliding – objects are treated as different. If hash codes are the same then Equals method is invoked.
General rule for GetHashCode method impementation: it should always return the same value in the whole object’s lifetime. It means properties used to calculate it should be immutable.
General rule for Equals method implementation: it should check for null and type of compared object.
You always should to implement GetHashCode method when you are overriding Equals method and vice versa.
What’s more when two objects have the same hashcodes, it doesn’t mean that they are identical. But when two objects are identical, they have the same hashcode.

    [TestClass]
    public class EqualsAndGetHashcodeTests
    {

        [TestMethod]
        public void TestComparing()
        {
            var p1 = new Person(1, "John", 1950);
            var p2 = new Person(2, "John", 1960);
            var p3 = new Person(1, "John", 1970);
            var p4 = new Person(1, "John", 1950);

            var people = new HashSet<Person>(); //hash set collects unique elements
            people.Add(p1); //p1 will be added as it is first unique item
            people.Add(p2); //p2 will be added as it has different hash code (equals method won't be called)
            people.Add(p3); //p3 will be added, hashcode is the same as for p1, but Equals method is called and will return false
            people.Add(p4); //p4 won't be added, as hashcode is the same as p1 and Equals method will return true
        }

        private class Person
        {
            public Person(int id, string name, int birthYear)
            {
                Id = id;
                Name = name;
                BirthYear = birthYear;
            }

            public int Id { get; private set; }
            public string Name { get; set; }
            public int BirthYear { get; set; }

            public override bool Equals(object obj)
            {
                if (obj == null)
                    return false;

                if (GetType() != obj.GetType())
                    return false;

                var theOtherPerson = obj as Person;

                return Name == theOtherPerson.Name && BirthYear == theOtherPerson.BirthYear;
            }

            public override int GetHashCode()
            {
                return Id;
            }
        }
    }

Notice that you can easily implement GetHashCode method for anonymous types like this:

            public override int GetHashCode()
            {
                return new { Id, BirthYear }.GetHashCode();
            }

For more about Equals method see: C# – Equals()

Collections – short comparison

Dictionary:
Containst pairs (key and value).
Items must correctly implement Equals() and GetHashCode() or IEqualityComparer must be passed in constructor.
Is fast for lookup and inserts.
Cannot be easily traversed in order (no sorting).
Implementation is hashtable.

SortedDictionary:
Containst pairs (key and value).
Key items must implement correctly IComparable.
Implementation is BinaryTree.
A little bit slowler than normal dictionary, but items are sorted.

List:
Contains items without keys.
Reading items by index is quick.
Removing or adding in the middle of is slow.
Implementation using array.
Is not sorted.

LinkedList:
Contains items without keys.
Adding and removing is quick.
Reading items directly by index is not possible, but in order is fast.

HashSet:
Contains unique items.
Fast lookup and adding, but no ordering.
Items must correctly implement Equals() and GetHashCode() or IEqualityComparer must be passed in constructor.

Stack:
Implementation of LIFO.
Fast lookup and adding, but only one element is accessible.

Queue:
Implemenatation of FIFO.
Fast lookup and adding, but only one element is accessible.

If you need thread-safe collection you should use concurrent collections from System.Collections.Concurrent namespace.

CodeDom – generate code dynamically

CodeDom is a feature which allows you to create code dynamically.
It means, you can define an object (System.CodeDom.CodeCompileUnit) which describes a new type to be created. Then you can print out prepared schema to file with c# code.
This sample shows how to prepare CodeCompileUnit for new class ‘Person’ and how to write code file with this class.

    class Program
    {
        static void Main(string[] args)
        {
            var template = CreateCodeTemplate("Person", 
                                        new Tuple<Type, string>(typeof(int), "Age"), 
                                        new Tuple<Type, string>(typeof(string), "Name"));
            var generatedFileName = GenerateCode(template);
            Console.WriteLine(generatedFileName);
            Console.ReadLine();
        }

        /// <summary>
        /// Creates schema of the code you want to generate. 
        /// Schema will contain class with given name and properties.
        /// </summary>
        /// <returns></returns>
        public static CodeCompileUnit CreateCodeTemplate(string className, params Tuple<Type, string>[] properties)
        {
            var mySample = new CodeCompileUnit();

            var myNamespace = new CodeNamespace("ExternalTool.Base");
            myNamespace.Imports.Add(new CodeNamespaceImport("System.Linq"));

            var myClass = new CodeTypeDeclaration(className);
            myClass.IsClass = true;
            myClass.Comments.Add(new CodeCommentStatement("Use this autogenerated class to create specific items."));

            foreach (var p in properties)
            {
                var privateMember = new CodeMemberField(typeof(int), "_" + p.Item2);

                var prop = new CodeMemberProperty();
                prop.Name = p.Item2;
                prop.Type = new CodeTypeReference(typeof(int));
                prop.GetStatements.Add(new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), privateMember.Name)));
                prop.SetStatements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), privateMember.Name), new CodePropertySetValueReferenceExpression()));

                myClass.Members.Add(privateMember);
                myClass.Members.Add(prop);
            }

            mySample.Namespaces.Add(myNamespace);
            myNamespace.Types.Add(myClass);

            return mySample;
        }

        /// <summary>
        /// Creates file with the C# code. Path to the created file is returned.
        /// </summary>
        /// <param name="template"></param>
        /// <returns></returns>
        public static string GenerateCode(CodeCompileUnit template)
        {
            var codeProvider = new CSharpCodeProvider();
            var fileName = Path.GetTempFileName();
            using (var writer = new StreamWriter(fileName, false))
            {
                var itWriter = new IndentedTextWriter(writer, "  ");// writes text with given tabbing
                codeProvider.GenerateCodeFromCompileUnit(template, itWriter, new CodeGeneratorOptions());
            }

            return fileName;
        }
    }

When the code above is started, file like this is generated:

//------------------------------------------------------------------------------
// <auto-generated>
//     Ten kod został wygenerowany przez narzędzie.
//     Wersja wykonawcza:4.0.30319.42000
//
//     Zmiany w tym pliku mogą spowodować nieprawidłowe zachowanie i zostaną utracone, jeśli
//     kod zostanie ponownie wygenerowany.
// </auto-generated>
//------------------------------------------------------------------------------

namespace ExternalTool.Base
{
    using System.Linq;


    // Use this autogenerated class to create specific items.
    public class Person
    {

        private int _Age;

        private int _Name;

        private int Age
        {
            get
            {
                return this._Age;
            }
            set
            {
                this._Age = value;
            }
        }

        private int Name
        {
            get
            {
                return this._Name;
            }
            set
            {
                this._Name = value;
            }
        }
    }
}

OutOfMemoryException – why?

Everybody knows OutOfMemory exception. As name says it is usually thrown when there is no more RAM on the computer, but it is not so clear as there are a few reasons why this exception can occur.

Possible reasons:
* There is no not allocated RAM memory on the computer – it means whole RAM installed on computer is used.
* Limit of the maximum allowed memory usage for a single .NET process is reached. It means that you still have free RAM to use, but single .NET process cannot use more. This limit depends on OS architecture.
* An huge (~2GB) object was trying to be allocated. Notice that .NET has a limit how big a single object can be.
* Too many threads are used in a single process. It means that plenty of RAM can be available, but limit for a number of threads is reached.

Further reading:
* http://stackoverflow.com/questions/13429129/task-vs-thread-differences
* http://stackoverflow.com/questions/13429129/task-vs-thread-differences
* https://support.microsoft.com/en-us/help/2020006/how-to-troubleshoot-out-of-memory-issues-system.outofmemoryexception-in-asp.net

See examples below. I show how some of these problems can be reproduced.

        /// <summary>
        /// Method starts threads one by one. Then there are more than 1000 threads it causes OutOfMemory exception (even when there is still not allocated memory available)
        /// </summary>
        private static void TooManyThreadsCauseOutOfMemory()
        {
            double value = 0;
            for (int i = 0; i <= 2000; i++)
            {
                Thread t = new Thread(() =>
                {
                    while (true)
                    {
                        value = new Random().NextDouble();
                        Thread.Sleep(10000);
                    }
                });
                t.Name = "My thread: " + i;
                t.Start();
            }
        }


        /// <summary>
        /// Opposite to threads, many tasks don't cause strange OutOfMemory exceptions. This can be solution for problem shown in example above.
        /// </summary>
        private static void ManyTasksDontCauseOutOfMemory()
        {
            double value = 0;
            Task.Factory.StartNew(() =>
            {
                while (true)
                {
                    value = new Random().NextDouble();
                    Thread.Sleep(10000);
                }
            }, TaskCreationOptions.None);
        }


        /// <summary>
        /// Many created objects cause out of memory exception, as there is a limit how much memory can be consumed by a single .NET process.
        /// In my environment when it reaches 1,5GB of memory, exception is thrown.
        /// Notice that I still have free RAM memory on my computer, but a single process has crossed its limit.
        /// </summary>
        private static void ManyObjectsCauseOutOfMemory()
        {
            var cummulativeCollection = new List<byte[]>();
            var sampleCollection = new byte[] { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 };
            while (true)
            {
                cummulativeCollection.Add(sampleCollection);
            }
        }

Unit Testing – Moq

Moq – it is library to mock your objects, return fake values. It is helpful when unit testing.
Imagine that you have Employee class and HrManager which performs any logic on Employees and you want to test this logic easily. Moq can be helpful in such situations.

See our code to be tested.

        public interface IEmployee
        {
            int SkillsLevel { get; }
            int ExperienceLevel { get; }
        }
        
        class Employee : IEmployee
        {
            public Employee(string lastName, int experience, int skills)
            {
                LastName = lastName;
                ExperienceLevel = experience;
                SkillsLevel = skills;
            }
            public string LastName { get; set; }

            public int ExperienceLevel { get; set; }
            public int SkillsLevel { get; set; }
        }

        class HrManager
        {
            public static IEmployee GetTheBestEmployee(IList<IEmployee> employees)
            {
                if (employees == null || employees.Count == 0)
                    throw new ArgumentNullException();

                return employees.ToList().OrderByDescending(e => e.SkillsLevel + e.ExperienceLevel).FirstOrDefault();
            }
        }

We would like to test HrManager.GetTheBestEmployee. We need a few instances of IEmployee to do this. Below you can see how mock can help in this situation. Notice that Employees are not instantiated in normal way. Mock allows you to setup only the required properties.

        [TestMethod]
        public void MoqUnitTest1()
        {
            var mockedEmployees = new List<IEmployee>();

            var e1 = new Moq.Mock<IEmployee>(); //create mocked IEmployee
            e1.Setup(x => x.SkillsLevel).Returns(5); //sets that SkillsLevel property will return value = 5, when called
            e1.Setup(x => x.ExperienceLevel).Returns(2); //sets that ExperienceLevel property will return value = 2, when called
            mockedEmployees.Add(e1.Object); //object here is IEmployee

            var e2 = new Moq.Mock<IEmployee>();
            e2.Setup(x => x.SkillsLevel).Returns(10);
            e2.Setup(x => x.ExperienceLevel).Returns(10);
            mockedEmployees.Add(e2.Object);

            var e3 = new Moq.Mock<IEmployee>();
            e3.Setup(x => x.SkillsLevel).Returns(2);
            e3.Setup(x => x.ExperienceLevel).Returns(1);
            mockedEmployees.Add(e3.Object);

            var theBestOne = HrManager.GetTheBestEmployee(mockedEmployees); //invoked method to be tested
            Assert.AreEqual<int>(10 * 10, theBestOne.SkillsLevel * theBestOne.ExperienceLevel); //assert
			
            e3.Verify(x => x.ExperienceLevel, Times.Once); //verifies whether property ExperienceLevel was called exactly once for this object
        }

More information: https://github.com/Moq/moq4/wiki/Quickstart