The hidden performance hit when using Get Methods

There are many ways to write a loop when using C#. But when iterating you need to be very much aware of the data you are iterating. If you are not being taking good enough care of your code you may suffer from bad performance. For example when using a property like this property public static List<string> Strings { get { Console.WriteLine("GET"); return new List<string> { "1", "2" }; } } Then you will get completely different results when using one of the following three methods to iterate the items for (int i = 0; i < Strings.Count; i++) { Console.WriteLine(Strings[i]); } For this example the list will be retrieved twice for each iteration of the items. The first problem here is the usage in i < Strings.Count, which for each iteration will retrieve the list and count the items. Then furthermore in Strings[i] the list will be retrieved once again. var l = Strings.Count; for (int i = 0; i < l; i++) { Console.WriteLine(Strings[i]); } This is a slightly better solution, where the length of the list is stored locally and thus preventing the recount for each iteration. Still foreach Strings[i] the list is retrieved, so the implementation is still a bad solution. var temp = Strings; for (int i = 0; i < temp.Count; i++) { Console.WriteLine(temp[i]); } This is again a better solution, where the entire list is stored locally and thus the list is retrieved only once and then the local copy is used for each iteration. When doing this you no longer need to worry about the implementation and performance of the get method, as it is only used once. foreach (string s in Strings) { Console.WriteLine(s); } Another solution if you need to iterate all the items, then you can just follow this example which simplifies the code and prevents you from having to store the list locally. The effect is the same as the previous example just without the boilerplate code. So this should just serve as an example to watch you when using get methods that you do not control. 

InvalidOperationException when setting track properties from a BackgroundAgent on Windows Phone

This is just a feature that I stumbled upon when I was updating my radio app I wanted to add an enhancement, so that when the radio was playing I wanted to display the current song on the lock screen (UVC). This should be very simple and just a matter of setting the information on the current track. So back in Visual Studio I wrote the following code: BackgroundAudioPlayer.Instance.Track.BeginEdit(); BackgroundAudioPlayer.Instance.Track.Artist = "Artist"; BackgroundAudioPlayer.Instance.Track.Title = "Title"; BackgroundAudioPlayer.Instance.Track.EndEdit(); And this all compiled fine enough. But when I started retesting my app, I got an InvalidOperationException, which seemed quite curious. After a bit of googling though I found the answer, which was actually quite simple. For some reason when you call BackgroundAudioPlayer.Instance.Track you do not always get the same object (at least not when doing it from a BackgroundAgent), so in effect that means, that when you call BeginEdit, you do that on one object, but then when you try setting the artist you get another object, which is not in edit mode and therefore the invalidoperation exception. Solving it was fairly easy and just required copying the current track to a local variable and working on it there, and then everything is running smoothly. So my code ended up like this and the problem was solved: var track = BackgroundAudioPlayer.Instance.Track; track.BeginEdit(); track.Artist = "Artist"; track.Title = "Title"; track.EndEdit();

Final resort for modifying your HTML output - Part 1

Using Response Filter For the first method of modifying the html output I can suggest using a Response Filter. This i a filter that you can attach to the response stream which means that all output is sent through your specific filter before it is outputted to the client. This means that we can make any modifications to the output that we should desire. As described in my intro the first solution to my problem can be solved using the following lines of code   First I add all this code to a file residing in the app_code folder of my website using System; using System.Web; using System.Text.RegularExpressions; using System.Text; using System.IO; public class RegexModule : IHttpModule { public void Dispose() {} public void Init(HttpApplication context) { context.ReleaseRequestState += new EventHandler(InstallResponseFilter); } private void InstallResponseFilter(object sender, EventArgs e) { HttpResponse response = HttpContext.Current.Response; HttpRequest request = HttpContext.Current.Request; response.Filter = new Replacer(response.Filter, HttpContext.Current.Response.ContentEncoding); } } public class Replacer : Stream { private static Regex ACTIONTARGETREPLACE = new Regex(@"<form.+action=""([^""]+)""[^>]+>", RegexOptions.Compiled); private static Regex eof = new Regex("</html>", RegexOptions.IgnoreCase | RegexOptions.Compiled); /// <summary> /// This methods takes all input which is normally sent directly to the browser and saves it all to an internal buffer /// which can then be manipulated /// </summary> /// <param name="buffer"></param> /// <param name="offset"></param> /// <param name="count"></param> public override void Write(byte[] buffer, int offset, int count) { string strBuffer = encoding.GetString(buffer, offset, count); // --------------------------------- // Wait for the closing </html> tag since the write method is called several times before it should actually be sent to the browser // --------------------------------- if (!eof.IsMatch(strBuffer)) resulthtml.Append(strBuffer); else { resulthtml.Append(strBuffer); string finalHtml = resulthtml.ToString(); string outputHtml = ACTIONTARGETREPLACE.Replace(finalHtml, delegate(Match m) { return m.Value.Replace(m.Groups[1].Value, "NEWACTIONTARGET"); }); byte[] data = encoding.GetBytes(outputHtml); response.Write(data, 0, data.Length); } } Stream response; StringBuilder resulthtml; Encoding encoding; public Replacer(Stream inputStream, Encoding encoding) { response = inputStream; this.encoding = encoding; resulthtml = new StringBuilder(); } public override bool CanRead { get { return true; } } public override bool CanSeek { get { return true; } } public override bool CanWrite { get { return true; } } public override void Close() { response.Close(); } public override void Flush() { response.Flush(); } public override long Length { get { return response.Length; } } public override long Position { get; set; } public override long Seek(long offset, SeekOrigin origin) { return response.Seek(offset, origin); } public override void SetLength(long length) { response.SetLength(length); } public override int Read(byte[] buffer, int offset, int count) { return response.Read(buffer, offset, count); } } Then I add the following line to my web.config file in the http modules section <add name="Replacer" type="RegexModule, App_Code"/> After I have done these changes all the form tags on my website now have their action property set to "NEWACTIONTARGET" as specified by my code

Final resort for modifying your HTML output - Intro

In order to answer some queries from different sources I have decided to start a mini series describing various ways for modifying your HTML output for at .NET website. These techniques can be useful in at least the following situations 1. You want to modify some HTML generated by webcontrols that are not under your control 2. You want to fix some common error which is generated on your pages (i.e. if you are using some HTML editor which does not provide the correct output for your website) 3. add more scenarios of your own choosing.   For my various samples I will keep the same goal in mind to show you how the same goal can be achieved using different methods. The goal I want to achieve is to modify the action of the form tag which is normally generated by the framework. This example is only chosen as an example of something which I cannot modify under normal circumstances   This post will be updated with links to the various parts of my series as I write them Part 1 - Using a response filter

Read metadata from images

Using the .NET 3.0 framework you can gain access to some of the metadata that is stored in images. What you need to do is add the following references to your project PresentationCore (part of the 3.0 framework)WindowsBase (Also part of the 3.0 framework) Then you can see from the following code how you can access some of the various properties found in the metadata   using System; using System.Windows.Media.Imaging; using System.IO; using System.Reflection; namespace ImageReader { class Program { static void Main(string[] args) { string filepath = @""; FileInfo f = new FileInfo(filepath); if (f.Exists) { using (FileStream fs = f.OpenRead()) { BitmapSource img = BitmapFrame.Create(fs, BitmapCreateOptions.IgnoreImageCache, BitmapCacheOption.None); double mpixel = (img.PixelHeight * img.PixelWidth) / (double)1000000; Console.WriteLine("ImageDimensions: {0}x{1} - {2}MP", img.PixelWidth, img.PixelHeight, mpixel); BitmapMetadata meta = (BitmapMetadata)img.Metadata; if (meta != null) { foreach (PropertyInfo inf in typeof(BitmapMetadata).GetProperties()) { if (inf.PropertyType == typeof(string) || inf.PropertyType == typeof(int) || inf.PropertyType == typeof(bool)) Console.WriteLine("{0}: {1}", inf.Name, inf.GetGetMethod().Invoke(meta, new object[0])); else if (inf.PropertyType == typeof(System.Collections.ObjectModel.ReadOnlyCollection)) { Console.WriteLine(new string('-', 80)); Console.WriteLine(inf.Name); object ob = inf.GetGetMethod().Invoke(meta, new object[0]); if (ob != null) { foreach (string r in ob as System.Collections.ObjectModel.ReadOnlyCollection) Console.WriteLine(" {0}", r); } Console.WriteLine(new string('-', 80)); } else Console.WriteLine(inf.PropertyType.FullName); } } fs.Close(); } } } } }

How to post a page using C#

If you should ever desire to do some webrequesting and posting some values to a webpage and afterwards reading the results. Then you can use the following snippet   using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.IO; namespace PageScraper { class Program { static void Main(string[] args) { string postdata = "q=control&field=value"; byte[] data = Encoding.Default.GetBytes(postdata); WebRequest w = WebRequest.Create(""); w.Method = "POST"; w.ContentType = "application/x-www-form-urlencoded"; w.ContentLength = data.Length; Stream s = w.GetRequestStream(); s.Write(data, 0, data.Length); s.Close(); HttpWebResponse resp = w.GetResponse() as HttpWebResponse; StreamReader sr = new StreamReader(resp.GetResponseStream()); string res = sr.ReadToEnd(); resp.Close(); Console.WriteLine(res); } } }

Find control

In order to find a control on a page, which my be nested in a repeater or another control, this method might be useful private Control FindNestedControl(Control parent, string controlid) { Control c = parent.FindControl(controlid); if (c != null) return c; else { foreach (Control child in parent.Controls) { c = FindNestedControl(child, controlid); if (c != null) return c; } } return null; } Which can be called with Page object as the initial Control, and then it iterates all the controls on the page untill it finds the correct one.