I am currently hunting down memoryleaks in our application and when it comes to viewmodels that execute any linq queries I find an object in memory with that namespace. I am using dotMemory to do the inspection and it lists the object with a +<>c ending. I have not found any explanation what kind of object this is and if it is a real issue that this resides in memory, but I have found out that it is connected to the linq query. Code that reprodce this and as you can see the Linq query result is never used.
public class myViewModel : PropertyChangedBase
{
public myViewModel()
{
var memissue = _dummyList.ToList().Any(c => c == false);
}
public string SomeBoundProperty
{
get { return _someBoundProperty; }
set
{
if (value == _someBoundProperty) return;
_someBoundProperty = value;
NotifyOfPropertyChange();
}
}
}
Snapshot from dotmemory:
I hope that someone can explain what kind of object a +<>c is and maybe why it is not released from memory or is this just the way that Linq works?
.ToList() enumerates the whole collection and stores a copy in memory. This is typically not useful if you aren't going to use all the information in the collection. Try removing .ToList() and see what happens. You should expect to see immediate savings.
To shed some light on the +<>c thing, I believe that comes from it being a generic type. I'm inferring from the code you provided that the type is really List<Boolean>.
Related
I'm in the midst of setting up an Umbraco 8 website and have run into some weird behaviour. The project is using .NET 4.7.2.
Basically, I have an IENumerable of type Event, a simple list of content that I'd like to render in to a list. However, whenever I do anything with the list (which has items), the list is immediately emptied. This includes simply assigning to a different variable, checking for null etc.
I don't believe this is an Umbraco 8 issue but for clarity, I'm currently running through a Surface Controller and render it by calling the following in my view:
#Html.Action("RenderUpcoming", "Events")
This is the controller:
using Index.Models.Events;
using Index.Models.PublishedContent;
using Papermoon.Umbraco.Kupo.Core.Services.Interfaces;
using System;
using System.Linq;
using System.Web.Mvc;
using Umbraco.Web.Mvc;
namespace Index.Web.Controllers.Surface
{
public class EventsController : SurfaceController
{
private readonly KupoGeneralSettings _kupoGeneralSettings;
public EventsController(IKupoSettingsService kupoSettingsService)
{
_kupoGeneralSettings = kupoSettingsService.GetSettings<KupoGeneralSettings>("kupoGeneralSettings");
}
public ActionResult RenderUpcoming()
{
UpcomingEventsModel model = new UpcomingEventsModel();
model.Title = "Upcoming Events";
model.Events = Umbraco.ContentAtXPath("root/homepage/events/event").Select(x => new Event(x));
model.Events = model.Events.Where(x => x.StartDate > DateTime.Now).OrderBy(x => x.StartDate).Take(3);
model.TotalEvents = model.Events.Count();
model.EventListingLink = _kupoGeneralSettings.EventListingLink;
return PartialView("~/Views/Partials/Events/UpcomingEvents.cshtml", model);
}
}
}
So here, when I call model.Events = model.Events.Where(x => x.StartDate > DateTime.Now).OrderBy(x => x.StartDate).Take(3); - I have results then when I do model.TotalEvents = model.Events.Count(); the list (model.Events) is then empty.
This also happens when I assign to another variable, when I call model.Events.Any(), or when I even do Model.Events != null.
It's potentially easier to show this than tell so see the accompanying gif of this happening: https://i.imgur.com/rE3VAqe.gif
Thanks,
Ben
Your IEnumerable comes from this call:
Umbraco.ContentAtXPath("root/homepage/events/event")
How it is done exactly I do not know since it's Umbraco business, but IEnuemerable itself allows "lazy" evaluation. It means that e.g. if you are reading from a SQL database without buffering it will read each time you iterate.
Depending on the data it can return same results or new results (if the data has changed). So what you get in IEnumerable depends totally on the implementation details, so if you reiterate you don't know what happens behind the scenes (ranging from nothing special to a new DB query).
To prevent this behavior when the source of IEnumerable is unknown you can do ToList() at the end of your query:
Umbraco.ContentAtXPath("root/homepage/events/event")
.Select(x => new Event(x))
.ToList();
What will happen is that you iterate through your collection once and add all elements to the list. This list won't change unless you do this yourself.
Sure – you don't know the actual type of the object other than that it's something you can iterate over (an IEnumerable).
It could be a generator that returns an infinite stream of things, for instance (well, in this case you know it's not).
If you need a concrete collection, you could use .ToList() to cast it into a List<> you can certainly iterate over multiple times.
I am working on a framework that uses some Attribute markup. This will be used in an MVC project and will occur roughly every time I view a specific record in a view (eg /Details/5)
I was wondering if there is a better/more efficient way to do this or a good best practices example.
At any rate, I have an a couple of attributes e.g:
[Foo("someValueHere")]
String Name {get;set;}
[Bar("SomeOtherValue"]
String Address {get;set;}
What is the most efficient way/best practice to look for these attributes/Act on their values?
I am currently doing something like this:
[System.AttributeUsage(AttributeTargets.Property)]
class FooAttribute : Attribute
{
public string Target { get; set; }
public FooAttribute(string target)
{
Target = target;
}
}
And in my method where I act on these attributes(simplified example!):
public static void DoSomething(object source)
{
//is it faster if I make this a generic function and get the tpe from T?
Type sourceType = source.GetType();
//get all of the properties marked up with a foo attribute
var fooProperties = sourceType
.GetProperties()
.Where(p => p.GetCustomAttributes(typeof(FooAttribute), true)
.Any())
.ToList();
//go through each fooproperty and try to get the value set
foreach (var prop in fooProperties)
{
object value = prop.GetValue(source, null);
// do something with the value
prop.SetValue(source, my-modified-value, null);
}
}
Attribute.GetCustomAttribute and PropertyInfo/MemberInfo.GetCustomAttribute is the recommended way of getting at attribute objects.
Although, I wouldn't normally enumerate all properties with attributes; you generally want to work a particular attribute so you'd just call GetCustomAttribute directly.If you're looking for attributes on any of your properties, enumerating those properties looking for attributes based on GetCustomAttribute() the way you're doing it, is the best way to do it.
There is not really much choice when dealing with attributes - your code is ok and reasonable as is, it is also unlikley to be your main performance concern. The only immediate thing is to drop ToList call as absolutely unnecessary.
Side notes: performance related question should look approximately
"I've measured my code and portion XXX seems to be taking too much time (YYY) . The time goal for this piece of code is ZZZ. Is my way of doing XXX reasonable/where can I improve it?".
Note that in you case you are missing YYY and ZZZ time portions - so you can't really say if it is slow for your case or not. And you may want to start measurements with DB/other IO bound operations as it more likely to speed up your overall code.
After you figured that this attribute related code is main perfomance issue you can consider some sort of caching of results or even code generation of some sort (either through caching lambdas that would set necessary values or even full blown IL generation).
To find the target of an ExpressionSyntax instance I call mySemanticModel.GetSymbolInfo(myExpressionSyntax).
I have several SemanticModel instances that each relate to a code file's syntax tree.
I want to iterate the semantic models and find the appropriate one to return the symbol information, but I can't see how to test for the appropriate semantic model without using exceptions.
I need the following code completing:
SymbolInfo? Resolve(ExpressionSyntax expressionSyntax)
{
foreach (SemanticModel semanticModel in allSemanticModels)
{
if ( /* test if expression syntax found in semantic model */ )
{
return semanticModel.GetSymbolInfo(expressionSyntax);
}
}
return null;
}
SemanticModels are bound to an underlying SyntaxTree, so you just need to make sure those lined up. If you had an IEnumerable<SemanticModel> you'd just have to do:
var model = models.First(m => m.SyntaxTree == expressionSyntax.SyntaxTree);
To pick out the right one; you're probably better off having a Dictionary<SyntaxTree, SemanticModel> rather than enumerating a list each time. I'm not sure exactly why you'd use any other data structure to hold them.
The only main advantage too of holding onto an SemanticModel is you get some caching benefits, trading memory in the process; don't be holding onto SemanticModels you're not going to use anymore.
I have a public class called Profile. Very simple model class currently with 2 properties; string Name and string Fields. As I develop the project the class will expand but it's not particularly important at the moment.
I have a Global static IList of type Profile called Profiles. I am quite new to manipulating the data in these IEnumerable types but I am looking to update one of the properties of a single profile. I have tried the following but I am receiving an object reference not set exception. The following is where I set the property:
Profiles.Single(x => x.Name == listBoxProfiles.Text).Fields = textBoxFieldName.Text;
The debugger is showing the listbox and textbox text properties both have the correct values so I think that it is the way I am using single that is wrong.
If anyone could shed some light I would be grateful.
A simple amendment to make the code more defensive is all that is required:
var profile = Profiles.SingleOrDefault(x => x.Name == listBoxProfiles.Text);
if (profile != null)
{
profile.Fields = textBoxFieldName.Text;
}
else
{
Profiles.Add(new Profile(textBoxFieldName.Text));
}
This code will cope with missing values, SingleOrDefault expects 0 or 1 items to be returned. It will throw an exception if more than 1 items are found.
If you know your code should always have the item you are looking for, then your code will work - but I'd advise against this style of programming in favour of being a little more defensive.
New to the MVC.net scene (and .net for that matter), but seems I find a wide array of options when wanting to populate a "list" with data. In my case at the moment, I'd like to populate a list from a select query of items and render the results in JSON for output, so bear with me....
So, my viewmodel class is something like :
[Serializable()]
public class TFSquery
{
public int MsgUid { get; set; }
public DateTime CreateStamp { get; set; }
}
And then I'd like to populate it with my query output:
List<TFSquery> z = (from msg in _DB.Msg
select new { msg.MsgUID, msg.CreateStamp }).ToList();
Then would I loop the output into my List so that I can then output in my Json return string? And when I use a LIST VS IENUMERABLE VS IQUERYABLE??
return Json(new { Result = z }, JsonRequestBehavior.AllowGet);
My rules of thumb:
Use a List when you have to add, remove, or refer to an item by index.
Use a IQueryable when you have to run ad-hoc queries against it.
Use IEnumerable by default.
It looks like you're already doing the query "in" your database, so I'd suggest using the simplest version: IEnumerable to simply be able to loop through the results.
If your new to .NET and C# I'd spend some time researching and becoming knowledgeable about what the different collection types are, how they differ, and when to use them. You'll use collections so often it you cannot afford to have a "simple one liner" summary understanding like the other answerers posted.
Here is a good guide on .NET collection types:
http://msdn.microsoft.com/en-us/library/0ytkdh4s.aspx
IQueryable is its own special beast and deserves its own guide:
http://msdn.microsoft.com/en-us/library/system.linq.iqueryable.aspx
Each interface has its own set of uses.
IQueryable is for deferred queries (that is, it saves the query but only executes it when it is enumerated)
IEnumerable can be enumerated and that's it.
IList can have items added and removed.