Domanda

Working in an application and there's the following extension method listed for Exceptions:

public static void FillData(this Exception target, object data)
{
   if (target == null)
      throw new ArgumentNullException("target");
   if (data == null)
      throw new ArgumentNullException("data");

   string stackTraceSite = target.LastStackTraceSite();
   var stringDict = new System.Collections.Specialized.StringDictionary();

   PropertyInfo[] pis = data.GetType().GetProperties();
   int pisLen = pis.Length;

   for (int i = 0; i < pisLen; i++)
   {
      string key = (stackTraceSite != null ? stackTraceSite + '.' : null) + pis[i].Name;
      try
      {
         target.Data[key] = pis[i].GetValue(data, null) ?? "null";
      }
      catch (ArgumentException ae)
      {
         target.Data[key] = "ARGUMENT EXCEPTION -> " + ae.Message;
      }
   }
}

This is then called or used in a similar fashion:

try
{
   // Perform some dangerous operation that throws an exception
}
catch (Exception ex)
{
   ex.FillData(new { CustId = 4, Category = "Foo", Style = "bar" });
   Logger.LogError(ex);
}

The members of the anonymous type (as in the example) are "reused" in some cases, but in many other cases they are quite different. (e.g. new { FileType = Enum.FileType.RejectionLetter, FilePath = loadFilePath })

This sort of code is used in quite a few locations and in a web app that's going to get a lot of traffic.. one question I'm wondering is: will the definition of all those anonymous classes eventually bog down / crash / create a significant memory load even if / when they aren't being caught?

È stato utile?

Soluzione

If the set of property names is the same, then the type will be reused.

class Program
{
    static void Main(string[] args)
    {

        var test = new Test();
        var inner = test.Go();
        var anonObj = new { Name = "one" };
        Console.WriteLine(inner == anonObj.GetType()); // true
    }
}

public class Test
{
    public Type Go()
    {
        var anonObj = new { Name = "one" };
        return anonObj.GetType();
    }
}

So you wouldn't run into problems from multiple calls with the same set of properties. But what about the definitions themselves? I wrote a quick experiment to see what would happen.

class Program
{
    static void Main(string[] args)
    {

        new Test().Go();
        Console.WriteLine("End: " + GC.GetTotalMemory(true));
        Console.ReadLine();
    }
}

public class Test
{
    public void Go()
    {
        var anonObj = new { Name = "one" };
        Console.WriteLine(GC.GetTotalMemory(true));
    }
}

The memory usage was higher after the anon type was declared, even after all references are gone and garbage collected, so I am assuming that the type definition does stick around after a GC, and thus is around for the life of the AppDomain. So in theory, it could be a problem.

However, it will only create types for unique combinations of properties, so unless this is a very large codebase, it should cause no problems.

Erick

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top