Svetlin Ralchev's Blog

Software Developer Adventures

How to prevent memory leaks when we are using events? (Part 1)

Posted by Svetlin Ralchev on January 21, 2010

In the average development lifecycle is possible that event handlers that are attached to events of sources to not be destroyed in coordination with the listener object that attached the handler to the source. Hence, this can lead to memory leaks. This cause the developers to take care about memory management not only when they use unmanaged resources but also when they attach new event handlers to specified event.

This problem is scaled, when Microsoft ships Windows Presentation Foundation due to the lifecycle of visual element in the framework. They addressed this issue with implementation of Weak Event Design Pattern.

But what should do if we are not using WPF? After my research regarding the pattern I realised that we need something which is more simple than porting or implementing the weak event pattern. My idea is to use Weak Reference object as host of each event that I want to be automatically memory managed by the GC. This may be easily achieved by generic class that will wraps event handler and make it possible to be used the same as event handlers are used. But unfortunately it could not be used in case of wrapping delegate, because GC will collect it on next collection. This happens, because nobody keeps reference to the method delegate.

Design

Lets create a generic class WeakEventHandler<TEventArgs>, which can received as type parameter only arguments inherited from EventArgs class. We will have 3 methods (for subscribe, unsubscribe and raise event). To make the class to look more natively as the trivial EventHandler<TEventArgs> we will create also operators +/- with EventHandler<TEventArgs> object.

diagram

As you can see the overridden operators +/- are very useful. It looks like that you are using normal event handler. You should create the weak event handler as private field and expose it as public event property. This achieves that the user (the programmer that use your API) thinks that he is using a normal event.

Conclusion

Weak References gives a very flexible mechanism for memory management, which allows the Garbage Collector to collect all objects that have been subscribed for specified event and are not used anymore and not referenced by anybody. But they still don’t resolve the issue, because the delegate is collected on the next Garbage Collection.

References

After I created this article I searched in Google, regarding this approach and found several guys that has the similar or same ideas it before me. You may check their articles and approaches:

Note: I edited the article, because I don’t want to give a wrong example of using WeakReference class. See Part 2, where the right usage will be shown. In the first version I did a little joke to provoke people to write. Thanks to Beat Keiner that found what is wrong :)

Posted in Articles | Tagged: , , | Leave a Comment »

PInvoke: Getting all child handles of window

Posted by Svetlin Ralchev on December 5, 2009

If you don’t know I have a new job in Bulgaria. I went away form Web Development and now I’m working as Winforms Developer. However, we had a client that exceed the number of window handles (more than 10 000) due to bad design of application. While diagnosing his application, we needed to understand how many handles are created and when they are born. :)

Reading MSDN I figure out that Windows API provide the availability to get all child handles for specified handle. We should use unmanaged EnumChildWindows function provided by user32.dll.

MSDN Definition

EnumChildWindows function enumerates the child windows that belong to the specified parent window by passing the handle to each child window, in turn, to an application-defined callback function. EnumChildWindows continues until the last child window is enumerated or the callback function returns FALSE.

Syntax

BOOL EnumChildWindows(
         HWND hWndParent,
         WNDENUMPROC lpEnumFunc,
         LPARAM lParam
);

hWndParent
          [in] Handle to the parent window whose child windows are to be enumerated.
lpEnumFunc
[in] Pointer to an application-defined callback function.
lParam
[in] Specifies an application-defined value to be passed to the callback function.

Note: If a child window has created child windows of its own, EnumChildWindows enumerates those windows as well.

How is used from .NET Framework

public class WindowHandleInfo

{

    private delegate bool EnumWindowProc(IntPtr hwnd, IntPtr lParam);

 

    [DllImport("user32")]

    [return: MarshalAs(UnmanagedType.Bool)]

    private static extern bool EnumChildWindows(IntPtr window, EnumWindowProc callback, IntPtr lParam);

 

    private IntPtr _MainHandle;

 

    public WindowHandleInfo(IntPtr handle)

    {

        this._MainHandle = handle;

    }

 

    public List<IntPtr> GetAllChildHandles()

    {

        List<IntPtr> childHandles = new List<IntPtr>();

 

        GCHandle gcChildhandlesList = GCHandle.Alloc(childHandles);

        IntPtr pointerChildHandlesList = GCHandle.ToIntPtr(gcChildhandlesList);

 

        try

        {

            EnumWindowProc childProc = new EnumWindowProc(EnumWindow);

            EnumChildWindows(this._MainHandle, childProc, pointerChildHandlesList);

        }

        finally

        {

            gcChildhandlesList.Free();

        }

 

        return childHandles;

    }

 

    private bool EnumWindow(IntPtr hWnd, IntPtr lParam)

    {

        GCHandle gcChildhandlesList = GCHandle.FromIntPtr(lParam);

 

        if (gcChildhandlesList == null || gcChildhandlesList.Target == null)

        {

            return false;

        }

 

        List<IntPtr> childHandles = gcChildhandlesList.Target as List<IntPtr>;

        childHandles.Add(hWnd);

 

        return true;

    }

}

We are using DLLImport attribute to expose the method in .NET Environment. The specific point is that we create a handle to the list where are collected all pointers, due to availability to access it from the callback function where we know which is the child handle.

References

Posted in Articles | Tagged: , , | Leave a Comment »

Snowflake Framework was born

Posted by Svetlin Ralchev on October 22, 2009

I’m glad to announce Snowflake Framework. I’m the founder and main contributor. I hope that will find other fellows that will be involved it the project. Initally it’s lightweight data access framework based on LINQ TO SQL.
You can find more information about it at http://snowflake.codeplex.com.
Code Plex

Posted in Bulletin | Tagged: , | Leave a Comment »

ADO.NET: XMLSerialization of extended DataTable

Posted by Svetlin Ralchev on October 18, 2009

Before 1,5 year I worked on the project, where we move all communication logic from .NET Remoting to WCF. In the architecture of the project our common transportation object is derived from Data Table. Due to some business rules this class has some additional fields. In .NET Remoting serialization of that kind of object works perfectly, but in WCF these additional fields isn’t serialized. The problem is due to changes serialization mechanism. Instead of binary serialization in .NET Remoting, in WCF serialization is XML based. In trying to solve this issue I created a post in MSDN Forums. Despite of that I found out the solution. This article explain my solution and give the community more clear view how to do it, instead of looking my old post in MSDN.

Lets say that we have this class that derives Data Table:

public class WcfDataTable : DataTable

{

    private string _ServerName;

 

    public WcfDataTable()

        : base()

    { }

 

    public WcfDataTable(string tableName)

        : base(tableName)

    { }

 

    public string ServerName

    {

        get { return this._ServerName; }

        set { this._ServerName = value; }

    }

}

 

 

Lets serialize instance of this class using XMLSerializer:wcf_table_screen

As you can see I’m creating dummy WcfDataTable object, which I’m cloning using xml serialization and deserialization. The cloned object is not identical with the original object, because this additional field is not initialized with the original value (it’s null). The existing xml serialization doesn’t catch the new field in the class. To make possible this field for xml serialization we should override the existing xml serialization, but how to do it? The solution is really simple. You have to implement the interface IXmlSerializable with explicit override of all its methods.

public class WcfDataTable : DataTable, IXmlSerializable

{

    private string _ServerName;

 

    public WcfDataTable()

        : base()

    { }

 

    public WcfDataTable(string tableName)

        : base(tableName)

    { }

 

    public string ServerName

    {

        get { return this._ServerName; }

        set { this._ServerName = value; }

    }

 

    void IXmlSerializable.ReadXml(System.Xml.XmlReader reader)

    {

        base.ReadXmlSchema(reader);

 

        XmlSerializer xmlSerializer = new XmlSerializer(typeof(string));

        this._ServerName = xmlSerializer.Deserialize(reader) as string;

 

        base.ReadXml(reader);

    }

 

    void IXmlSerializable.WriteXml(System.Xml.XmlWriter writer)

    {

        base.WriteXmlSchema(writer);

 

        XmlSerializer xmlSerializer = new XmlSerializer(typeof(string));

        xmlSerializer.Serialize(writer, this._ServerName);

 

        base.WriteXml(writer, XmlWriteMode.DiffGram);

    }

}

 

To do this workaround we have to override WriteXml and ReadXml method explicitly. The methods ReadXmlSchema and WriteXmlSchema are used to read and write the schema of data table, then we can read or write our data. Hence we can write/read our new field and then to invoke basic logic for serialization or deserializtion. So we reach our goal:

 

wcf_table_screen_done

After this workaround you can see that our new field is serialized and deserialized successfully.

Posted in Articles | Tagged: | 2 Comments »

LINQ to help: Create generic method to load entity by primary key

Posted by Svetlin Ralchev on October 11, 2009

After a short chat with my ex-colleague asking me to help him to create generic method that loads any entity class from the database I decided to write this article in case of somebody needs the same in his project. By the way thank you Teodor for my inspiration to do it.

Scenario

We are implementing our data access layer based on LINQ TO SQL. In the specifications that were created by our software architect is required to have generic method that load from the data base any record into entity object by primary key.

public class LINQGateway<TEntity> where TEntity : class

{

    private IDbConnection _DbConnection;

    public LINQGateway(IDbConnection connection)

    {

        this._DbConnection = connection;

    }

    public TEntity GetEntityByPrimaryKey(object pkKey, params object[] pkKeys)

    {

        // TO DO

    }

}

 

Problem

We become stuck, because each table has different primary key (count, name and data type of the primary key columns). So how to create a method that can be used in any case of  loading a record from the database by primary key. So we are facing the challenge how to implement GetEntityByPrimaryKey.

The Algorithm

1. Get tha mapping of the entity type
2. Use information for the mapping
  2.1 to get the name of the columns
  2.2 to get the name of the columns included in the primary key
3. Generate the T-SQL Query
4. Execute the Query via LINQ Framework to retrive the result as entity object

Before explain my approach to implement the algorithm above I want to explain you how linq expressions are executed.

Implementation and Solutions

I figured out 2 soltuions that are almost the same. The first solution (the simplest one) uses standard T-SQL that is translated by LINQ. The second one is using dynamic lambda expressions to build LINQ Query that is used to get the entity from the database.

Solution No.1

This is the easiest and simple way to get a entity by primary key. This is the solution that I gave to my colleague.

        public TEntity GetEntityByPrimaryKey(object pkKey, params object[] pkKeys)

        {

            List<object> primaryKeys = new List<object>();

            primaryKeys.Add(pkKey);

            primaryKeys.AddRange(pkKeys);

 

            TEntity entity = null;

            Type entityType = typeof(TEntity);

 

            using (DataContext dataContext = new DataContext(this._DbConnection))

            {

                dataContext.Log = new DebuggerWriter();

                dataContext.ObjectTrackingEnabled = false;

 

                Table<TEntity> table = dataContext.GetTable<TEntity>();

 

                MetaType metaEntityType = dataContext.Mapping.GetMetaType(entityType);

 

                var primaryKeyColumns = from pkColumn in metaEntityType.DataMembers

                                        where pkColumn.IsPrimaryKey

                                        select pkColumn;

 

                var columns = from col in metaEntityType.DataMembers

                              where col.IsPersistent && !col.IsAssociation

                              orderby col.Ordinal

                              select "[t0].[" + col.MappedName + "]";

 

                string selectColumns = String.Join(", ", columns.ToArray());

 

                int pkColumnsCount = 0;

 

                if (primaryKeyColumns != null)

                    pkColumnsCount = primaryKeyColumns.Count();

 

                if (pkColumnsCount == 0)

                    throw new InvalidOperationException("Table doesn’t have primary key");

 

                if (pkColumnsCount != primaryKeys.Count)

                    throw new InvalidOperationException("Primary key values doesn’t match primary key columns.");

 

 

                string tableName = metaEntityType.Table.TableName;

 

                if (tableName.Contains(‘.’))

                {

                    string[] splittedTablename = metaEntityType.Table.TableName.Split(‘.’).Select(p => "[" + p + "]").ToArray();

                    tableName = String.Join(".", splittedTablename);

                }

 

                StringBuilder builder = new StringBuilder("SELECT " + selectColumns + Environment.NewLine + "FROM " + tableName + " AS [t0]" + Environment.NewLine + "WHERE ");

 

                int index = 0;

 

                foreach (MetaDataMember pkColumn in primaryKeyColumns)

                {

                    string columnName = pkColumn.Name;

                    string paramID = index.ToString(CultureInfo.InvariantCulture);

                    builder.Append("[t0].[" + columnName + "] = {" + paramID + "}");

 

                    if (index + 1 != pkColumnsCount)

                        builder.Append(" AND ");

 

                    index++;

                }

 

                string query = builder.ToString();

                entity = dataContext.ExecuteQuery<TEntity>(query, primaryKeys.ToArray()).SingleOrDefault();

            }

 

            return entity;

        }

 

Solution No.2

This is the solution is more complicated than the one above.

public TEntity GetEntityByPrimaryKey(object pkKey, params object[] pkKeys)

{

    List<object> primaryKeys = new List<object>();

    primaryKeys.Add(pkKey);

    primaryKeys.AddRange(pkKeys);

 

    TEntity entity = null;

    Type entityType = typeof(TEntity);

 

    using (DataContext dataContext = new DataContext(this._DbConnection))

    {

        dataContext.Log = new DebuggerWriter();

        dataContext.ObjectTrackingEnabled = false;

 

        Table<TEntity> table = dataContext.GetTable<TEntity>();

 

        MetaType metaEntityType = dataContext.Mapping.GetMetaType(entityType);

 

        var primaryKeyColumns = from pkColumn in metaEntityType.DataMembers

                                where pkColumn.IsPrimaryKey

                                select pkColumn;

 

        int pkColumnsCount = 0;

 

        if (primaryKeyColumns != null)

            pkColumnsCount = primaryKeyColumns.Count();

 

        if (pkColumnsCount == 0)

            throw new InvalidOperationException("Table doesn’t have primary key");

 

        if (pkColumnsCount != primaryKeys.Count)

            throw new InvalidOperationException("Primary key value doesn’t match primary key columns.");

 

        ParameterExpression paramExpression = Expression.Parameter(entityType, "entity");

 

        BinaryExpression whereExpression = null;

 

        int index = 0;

 

        foreach (MetaDataMember pkColumn in primaryKeyColumns)

        {

            object value = primaryKeys[index];

            string columnName = pkColumn.Name;

 

            if (value != null && value.GetType() != pkColumn.Type)

            {

                Type paramType = value.GetType();

                string exceptionMsg = String.Format("The type ‘{0}’ of parameter ‘{1}’ is different than its column ‘{2}’ type ‘{3}’", paramType, value, columnName, pkColumn.Type);

                throw new InvalidOperationException(exceptionMsg);

            }

 

            BinaryExpression condition = Expression.Equal(Expression.Property(paramExpression, columnName), Expression.Constant(value));

 

            if (whereExpression != null)

                whereExpression = Expression.And(whereExpression, condition);

            else

                whereExpression = condition;

 

            index++;

        }

 

        Expression<Func<TEntity, bool>> predicate = Expression.Lambda<Func<TEntity, bool>>(whereExpression, new ParameterExpression[] { paramExpression });

        entity = table.SingleOrDefault(predicate);

    }

 

    return entity;

}

 

Conclusion

  In Solution No.1 we generate T-SQL string that is executed by LINQ and the result is translated as entity object. Insead of this in Solution No.2 we created dynamic LINQ expression that is translated by LINQ TO SQL Framework to T-SQL, which expected to be costly. So I did some tests in Northwind database to prove my expectations.
  Solution No.1 loads 1 record from table Employees for 315 milliseconds (average speed) againts 292 milliseconds (average speed) for Solution No.2. So I can’t say which implementation is the best way to resolve the task. Presently I’m in doubt about that. Why solution no.2 is faster than Solution no.1? I hope that I will give the aswer of this question soon in further posts.

Posted in Articles | Tagged: , , | Leave a Comment »

My Home Workstation

Posted by Svetlin Ralchev on October 1, 2009

DSC00712

Posted in Bulletin | 1 Comment »

Happy new name, dear blog

Posted by Svetlin Ralchev on September 11, 2009

As you see, my blog has new domain name. Instead of the old one http://ralch.wordpress.com I bought http://blog.ralch.com. My blog will be part of my domain http://www.ralch.com where I’ll try to contribute to the whole internet community with my professional work as software developer and sharing my hobbies and experiences.

Posted in Bulletin | 1 Comment »

Funny C# Code

Posted by Svetlin Ralchev on August 11, 2009

Even though I don’t know the author of the lines below I would say “Thank you man”. I recieved them today on skype by one of my ex-collegues.

        try

        {

        HOME:

            do

            {

                Play(“World of Warcraft”);

            }

            while (!asleep);

 

            Thread.Sleep(12 * 60 * 60 * 1000);

 

            WakeUp(coffee);

 

            if (you_still_give_a_shit())

                goto WORK;

            else

                goto OUT;

 

 

 

        WORK:

            do

            {

                if (got_something_to_do())

                {

                    LookAtTheMonitor();

                    Press_Some_Keys(new string[] { “Ctrl+C”, “Ctrl+V” });

                }

 

 

 

                Browse(“vbox7.com”);

                Browse(“topsport.bg”);

                Browse(“youtube.com”);

 

                Have_a_Break();

                Have_a_Kitkat();

 

            }

            while (DateTime.Now.Hour < 5);

 

 

 

            if (DateTime.Now.Day == 1)

            {

                // at least

                GetSomeCash(3000);

            }

 

 

 

        OUT:

            switch (mood)

            {

 

                case Mood.Horny:

                    ChaseChicks(“hot!”);

                    break;

                case Mood.Dull:

                    SmokeSomeStuff(new Stuff[] { “Grass”, “Serious Stuff” });

                    break;

                default:

                    DrinkBeer(5);

                    break;

 

            }

            goto HOME;

 

        }

        catch (HealthException x)

        {

            SeeTheDoctor(x);

        }

        catch (NoMoneyException)

        {

            ShitHappens();

        }

Posted in Bulletin | Tagged: , | 10 Comments »

DevReach 2009, Let’s GO

Posted by Svetlin Ralchev on August 4, 2009

This year is coming the new edition of DevReach in 12-13 October 2009 Sofia, Bulgaria. DevReach is one of the best developers conferences in Southeastern Europe. It is with 3 years history and people that attending each year growing. The presented technologies are Microsoft Frameworks (everything around .NET) and some fundamental practices (Design Patterns, Software Architectures and QA). You can see more information here.

The presentations are really impressive and I regret that I can’t go. The lecturers will be many MVPs and Microsoft Legends that we know from their blogs ;-) . It will be separated to 4 sessions:

So don’t miss it.

Posted in Bulletin | Tagged: | Leave a Comment »

TypeForwardedTo, what is that?

Posted by Svetlin Ralchev on July 31, 2009

“What is that?”

I asked my self, when I started today to read MCTS Self-Paced Training Kit (Exam 70-536). I found that this feature is since .NET Framework 2.0, but obviously something new for me :-) . The benefit that give us is to move types from one assembly to another  without changing the assemblies that use the moved types.

The common scenario:

  • We have already deployed application with many assemblies
  • We don’t want to re-deloy the whole application
  • We need to move the existing classes in other assembly that needs it, because of cross-reference issue

Here is my dummy project:

FtpDiagram

So we have deployed to several instances of FTPClient application. Each instance includes the following assemblies: FTPConsole.exe, FTPUtilities.dll and FTPLib.dll. The references are as the diagram above. In developing the new version of the application we need to do some changes in FTPLib only, but this affect moving the definition of class from FTPUtilities assembly to FTPLib assembly. If this is happened, we need to rebuild the application, because this class is used by FTPConsole.exe.  But we again face the problem: We have to deploy the big FTPConsole.exe with the other asseblies.

How can we avoid re-deploying of the whole application?

The answer and the solution is hidden by one line. We have to declare TypeForwardedTo attribute in AssemblyInfo.cs of  FTPUtitlities assembly. The important here is to NOT rename the namespace of the class that we move in the other FTPLib assembly. So if the type was in the namespace FTPUtilities (in FTPUtilities assembly), it should be in the same namespace in FTPLib assembly.  Then after we have moved the specified type, we need to put the following attribute in AssemblyInfo.cs (FTPUtilities assembly):

[assembly: TypeForwardedTo(typeof('Namespace.MovedType'))]

Then we need only to rebuild FTPLib assembly with the new features and FTPUtilities with the attribute above and to replace the old assemblies in the instances with this new one without touching FTPClient.exe. Really nice feature of .NET Framework.

Note: If the type that we are moving is instanciated or used directly by FTPClient assembly then this assembly won’t be buildable after the movement (because it doesn’t have reference to FTPLib.dll). But obviously it the purpose of this mechanism is to update only parts of the already installed applications.

Good luck guys

Posted in Articles | Tagged: , | 2 Comments »