<?xml version='1.0' encoding='UTF-8'?><rss xmlns:atom='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0' version='2.0'><channel><atom:id>tag:blogger.com,1999:blog-938730668763769016</atom:id><lastBuildDate>Wed, 14 Mar 2012 20:26:13 +0000</lastBuildDate><category>ui</category><category>tdd</category><category>ddd</category><category>java</category><title>Boris Byk</title><description>Java/.NET and more.</description><link>http://www.borisbyk.com/</link><managingEditor>noreply@blogger.com (Boris Byk)</managingEditor><generator>Blogger</generator><openSearch:totalResults>8</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-938730668763769016.post-3082638628868380592</guid><pubDate>Fri, 03 Feb 2012 05:27:00 +0000</pubDate><atom:updated>2012-02-02T21:30:24.625-08:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>java</category><category domain='http://www.blogger.com/atom/ns#'>tdd</category><category domain='http://www.blogger.com/atom/ns#'>ddd</category><category domain='http://www.blogger.com/atom/ns#'>ui</category><title>Domain Model vs View Model</title><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;h2&gt;Domain Model vs View Model&lt;/h2&gt;&lt;br /&gt;What do you think about &lt;a href="http://en.wikipedia.org/wiki/Separation_of_concerns"&gt;separation of concerns (SoC)&lt;/a&gt;? Isn't it that OOP was invented for? At least to alleviate the process.&lt;br /&gt;&lt;br /&gt;Although most modern programming languages have OOP stuff in it, developers often tend to use objects in a functional way. It is common thing nowadays that you can see a lot of classes working essentially as utilities. They take data in arguments of their methods and change them. This is what is often called &lt;a href="http://martinfowler.com/bliki/AnemicDomainModel.html"&gt;anemic domain model&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I prefer to follow another paradigm - &lt;b&gt;rich domain model&lt;/b&gt; and below in the article I will illustrate the idea. Besides I will show difference between Doman Model and View Model when dealing with UI.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Domain Model&lt;/h3&gt;&lt;br /&gt;Here we go. Imagine you have to implement UI that changes names of files. To see what I am talking about, open your favorite file manager, pick a file, right click on it and select "Rename". You will probably see either a dialog or an in-place editor to change name of the file.&lt;br /&gt;&lt;br /&gt;Let's consider what is domain model here. As domain model is all about rules, calculations etc, I would say that it is all about rules which a file name should comply with.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;public class FileDomain {&lt;br /&gt;    private static final String RESERVED_CHARS = ":*/&amp;lt;&amp;gt;?\|";&lt;br /&gt;    public static final int MAX_LEN = 256;&lt;br /&gt;&lt;br /&gt;    public boolean isCharAllowed(char c) {&lt;br /&gt;        boolean foundInReserved = RESERVED_CHARS.indexOf(c) &amp;gt; -1;&lt;br /&gt;        return !foundInReserved;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public boolean isLengthAllowed(int len) {&lt;br /&gt;        boolean isWithinAllowedRange = len &amp;gt;= 0 &amp;amp;&amp;amp; len &amp;lt;= MAX_LEN;&lt;br /&gt;        return isWithinAllowedRange;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public boolean isNameCorrect(@NotNull String name) {&lt;br /&gt;        assert name != null;&lt;br /&gt;&lt;br /&gt;        if (!isLengthAllowed(name.length()))&lt;br /&gt;            return false;&lt;br /&gt;        for (char c : name.toCharArray()) {&lt;br /&gt;            if (isCharAllowed(c))&lt;br /&gt;                return false;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        return true;&lt;br /&gt;    }&lt;br /&gt;....&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This piece of code is authoriative for any rules about file names. And we have to consult it from any other subsystem. Though the example works with just a static read-only state, it uses an OOP paradigm - encapsulation. There can be also non-static state to encapsulate:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;public class FileDomain {&lt;br /&gt;    ...&lt;br /&gt;    File file;      &lt;br /&gt;    ...&lt;br /&gt;&lt;br /&gt;    public String getName() {&lt;br /&gt;        return file.getName();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void setName(@NotNull String newName) throws BadFileNameException {&lt;br /&gt;        assert newName != null;&lt;br /&gt;&lt;br /&gt;        if (isNameCorrect(newName))&lt;br /&gt;            throw new BadFileNameException(newName);&lt;br /&gt;&lt;br /&gt;        file.setName(newName);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    ...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;What's the File here? In this example File is another piece of functionality that you want to separate from the logic. File represents operations on your file-system. That can be an OS backed filesystem or you can maintain your own one that you decided to store in DB. In the model implementation you are separated from this specific through the interface:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;public interface File {&lt;br /&gt;    ...&lt;br /&gt;    String getName();&lt;br /&gt;    void setName(String value);&lt;br /&gt;    ...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This is actually a &lt;a href="http://en.wikipedia.org/wiki/Bridge_pattern" title="Bridge pattern"&gt;bridge pattern&lt;/a&gt; employed here. It is convenient to use the pattern if you plan to write unit-tests for your domain objects. What you have to do in this case is to create a mocked implementation of the File and set it into your instance of FileDomain:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;FileDomain fileDomain = new FileDomain();&lt;br /&gt;File file = EasyMock.createStrictMock(File.class);&lt;br /&gt;fileDomain.file = file;&lt;br /&gt;&lt;br /&gt;//record expectations for file&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;On other hand you could use an inheritor of FileDomain that would override an abstract method to save file names:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;public class FileDomain {&lt;br /&gt;    ...&lt;br /&gt;    public void setName(@NotNull String newName) throws BadFileNameException {&lt;br /&gt;        assert newName != null;&lt;br /&gt;&lt;br /&gt;        if (isNameCorrect(newName))&lt;br /&gt;            throw new BadFileNameException(newName);&lt;br /&gt;&lt;br /&gt;        persistName(newName);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    protected abstract void persistName(String newName);&lt;br /&gt;    ...&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class FileSystemFile extends FileDomain {&lt;br /&gt;    ...&lt;br /&gt;    @Override&lt;br /&gt;    protected void persistName(String newName) {&lt;br /&gt;        ...&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Our domain model class encapsulates operations on its static and non-static state. The former one is represented by instance of File.&lt;br /&gt;&lt;br /&gt;Now if you get the hang of it, let's consider how View Model would look like.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;View Model&lt;/h3&gt;&lt;br /&gt;From UI perspective the domain is different. Ok not completly different but, say, extended. It's mostly about how it looks and feels rather than be persisted.&lt;br /&gt;&lt;br /&gt;What you can see in UI here is essentially a UI component that has 2 modes. It can either render the file name or edit it. Besides being in edit mode it keeps track of text entered, selection, copy/paste etc.&lt;br /&gt;&lt;br /&gt;All the stuff is going to be controled by your View Model that basically represents your domain logic for this piece of UI. Let's take a look at the state that your View model will maintain. For simplicity sake I will skip selection though:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;public class ViewDomain {&lt;br /&gt;    private bool isInEditMode;&lt;br /&gt;    private FileDomain fileDomain;&lt;br /&gt;    private StringBuilder temporaryFileName;&lt;br /&gt;&lt;br /&gt;    ...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;It is time to mention that I am going &lt;a href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller" title="MVC pattern"&gt;MVC&lt;/a&gt; way on the UI side. That assumes I will use my model from a controller that reacts on events from one or more views.&lt;br /&gt;&lt;br /&gt;Suppose user presses a key and that is an event that will be eventually handled in the controller. And the controller has to consult my model. If in read mode and 'e' is presssed it will ask model to switch to edit mode. By contrast, if in edit mode, controller will ask model to append the character to the &lt;i&gt;temporaryFileName&lt;/i&gt; if allowed character is provided or length is within the range:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;public class ViewDomain {&lt;br /&gt;    ...&lt;br /&gt;    public bool isInEditMode() {&lt;br /&gt;        return isInEditMode;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void startEditing() {&lt;br /&gt;        isInEditMode = true;&lt;br /&gt;        temporaryFileName.setLength(0);&lt;br /&gt;        temporaryFileName.append(fileDomain.getName());&lt;br /&gt;&lt;br /&gt;        fireSwitchedToEditModeEvent();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public String getTemporaryFileName() {&lt;br /&gt;        return temporaryFileName.toString();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void appendChar(char c) {&lt;br /&gt;        if (!fileDomain.isLengthAllowed(temporaryFileName.length() + 1);&lt;br /&gt;            fireOutOfLengthAllowed(FileDomain.MAX_LEN);&lt;br /&gt;&lt;br /&gt;        if (!fileDomain.isCharAllowed(c))&lt;br /&gt;            fireCharNotAllowedEvent(c);&lt;br /&gt;&lt;br /&gt;        temporaryFileName.append(c);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void acceptEdit() {&lt;br /&gt;        try {&lt;br /&gt;            fileDomain.setName(temporaryFileName.toString());&lt;br /&gt;            stopEditing();&lt;br /&gt;        } catch (BadFileNameException e) {&lt;br /&gt;            // still we can receive this if model rules are changed&lt;br /&gt;            fireBadFileNameEvent(e)&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void stopEditing() {&lt;br /&gt;        isInEditMode = false;&lt;br /&gt;        temporaryFileName.setLength(0);&lt;br /&gt;&lt;br /&gt;        fireSwitchedToReadModeEvent();&lt;br /&gt;    }&lt;br /&gt;    ...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You might have noticed that the View Model tends to fire events rather than throw exceptions. That's according to MVC paradigm. View listens to Model and &lt;b&gt;had to be notified&lt;/b&gt; about any change in state that has just happened. Upon being notified View will query the model and render a new look or show errors which are also a part of view.&lt;br /&gt;&lt;br /&gt;Again we see that the &lt;i&gt;ViewModel&lt;/i&gt; employes one of the base OOP paradigm: encapsulation. And the &lt;i&gt;ViewModel&lt;/i&gt; delegates some behavior to &lt;i&gt;FileDomain&lt;/i&gt; aggregating the instance of the object.&lt;br /&gt;&lt;br /&gt;Now let's say you want to put all the stuff together:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java"&gt;public class Controller {&lt;br /&gt;    private ViewModel model;&lt;br /&gt;&lt;br /&gt;    public Controller(@NotNull ViewModel model, @NotNull View view) {&lt;br /&gt;        assert model != null;&lt;br /&gt;        assert view != null;&lt;br /&gt;&lt;br /&gt;        this.model = model;&lt;br /&gt;        view.addKeyPressedListner(onKeyPressed);&lt;br /&gt;    }       &lt;br /&gt;&lt;br /&gt;    public void onKeyPressed(char c) {&lt;br /&gt;        if (model.isInEditMode()) {&lt;br /&gt;            // check if c is a controll key and call different model methods&lt;br /&gt;            ...&lt;br /&gt;            model.append(c);&lt;br /&gt;        } else if (c == 'e') // e - control key to start editing&lt;br /&gt;            model.startEdit();&lt;br /&gt;    }&lt;br /&gt;    ...&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class View {&lt;br /&gt;    private ViewModel model;&lt;br /&gt;&lt;br /&gt;    public View(@NotNull ViewModel model) {&lt;br /&gt;        assert model != null;&lt;br /&gt;&lt;br /&gt;        this.model = model;&lt;br /&gt;&lt;br /&gt;        model.addSwitchedToEditModeEventListner(onSwitchedToEditMode);&lt;br /&gt;        model.addSwitchedToReadModeEventListner(onSwitchedToReadMode);&lt;br /&gt;        model.addCharNotAllowedEventListner(onCharNotAllowed);          &lt;br /&gt;    }&lt;br /&gt;    ...&lt;br /&gt;    public void onCharNotAllowed(char c) {&lt;br /&gt;        showErrorPopup("The char entered is forbidden: " + c);&lt;br /&gt;    }&lt;br /&gt;    ...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I intentionally did not use any specific UI MVC framework to build up the examples. My goal was to demostrate concepts and how the pieces of concern are separated so each of them was responsible only for its own functionality.&lt;br /&gt;&lt;br /&gt;Besides the both &lt;i&gt;FileDomain&lt;/i&gt; and &lt;i&gt;ViewModel&lt;/i&gt; in the examples can be easily covered with unit-tests. And I guess some functionality of controllers can be covered too.&lt;br /&gt;&lt;br /&gt;Another benefit of the granularity is ability to put a mocked view implementation and run subset of integration tests for UI.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Summary&lt;/h3&gt;&lt;br /&gt;View Model can be considered as a subset of Domain Model that encloses UI specific concerns.&lt;br /&gt;&lt;br /&gt;Our &lt;i&gt;FileDomain&lt;/i&gt; class addresses just persistence concerns, rules and core behavior. From the &lt;i&gt;FileDomain&lt;/i&gt; perspective the class is agnostic of ways it will be eventually used.&lt;br /&gt;&lt;br /&gt;The &lt;i&gt;ViewModel&lt;/i&gt; operates on UI-centric state and can control intermediate state and behavior that is not related to file name logic directly, e.g. selection.&lt;br /&gt;&lt;br /&gt;It is possible to implement View Model class as an inheritor of Domain Model class or encapsulate Domain Model class inside View Model class. &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/938730668763769016-3082638628868380592?l=www.borisbyk.com' alt='' /&gt;&lt;/div&gt;</description><link>http://www.borisbyk.com/2012/02/domain-model-vs-view-model.html</link><author>noreply@blogger.com (Boris Byk)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-938730668763769016.post-7241454047977489680</guid><pubDate>Tue, 25 Aug 2009 03:07:00 +0000</pubDate><atom:updated>2012-01-23T23:30:21.127-08:00</atom:updated><title>How to check signature in MySpace iframe application (.net version)</title><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div&gt;It was a kind of headache for me after I decided to add checking signature to our MySpace application. I couldn't make it work using existing tools like the &lt;a href="http://www.codeplex.com/myspacetoolkit" target="_blank"&gt;MySpaceToolkit&lt;/a&gt;. But eventually I was able to do it myself. I cannot say it was painless. There were several examples in php like this &lt;a href="http://developer.myspace.com/Community/forums/p/4616/21822.aspx" target="_blank"&gt;one,&lt;/a&gt; that could bring even more questions than answers.  But they meant to be working and my code started working too though having eaten a plenty of my time. Here is the complete code:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c#"&gt;private static string GenerateIFrameSignature(HttpRequest req, string secretKey)&lt;br /&gt;{&lt;br /&gt;    const string c_unreservedChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~";&lt;br /&gt;&lt;br /&gt;    // We cannot use the HttpUtility.UrlEncode method because it produces lowercase output as OAuth requires uppercase.&lt;br /&gt;    // The code of the delegate was extracted out of MySpaceToolkit library.&lt;br /&gt;    Func&lt;string, string&gt; UrlEncode = (value) =&gt;&lt;br /&gt;    {&lt;br /&gt;        StringBuilder result = new StringBuilder();&lt;br /&gt;&lt;br /&gt;        foreach (char symbol in value)&lt;br /&gt;        {&lt;br /&gt;            if (c_unreservedChars.IndexOf(symbol) != -1)&lt;br /&gt;            {&lt;br /&gt;                result.Append(symbol);&lt;br /&gt;            }&lt;br /&gt;            else&lt;br /&gt;            {&lt;br /&gt;                result.Append('%' + String.Format("{0:X2}", (int)symbol));&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        return result.ToString();&lt;br /&gt;    };&lt;br /&gt;&lt;br /&gt;    var sortedKeysWOSig = req.QueryString.AllKeys.Where(k =&gt; k != "oauth_signature").OrderBy(k =&gt; k);&lt;br /&gt;    var query = new StringBuilder();&lt;br /&gt;&lt;br /&gt;    foreach (string key in sortedKeysWOSig)&lt;br /&gt;    {&lt;br /&gt;        if (query.Length &gt; 0) query.Append('&amp;');&lt;br /&gt;&lt;br /&gt;        query.Append(UrlEncode(key))&lt;br /&gt;        .Append('=')&lt;br /&gt;        .Append(UrlEncode(req.QueryString[key]));&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    StringBuilder @base = new StringBuilder();&lt;br /&gt;        @base.Append("GET&amp;")&lt;br /&gt;        .Append(UrlEncode(req.Url.GetComponents(UriComponents.SchemeAndServer | UriComponents.Path, UriFormat.Unescaped)))&lt;br /&gt;        .Append('&amp;')&lt;br /&gt;        .Append(UrlEncode(query.ToString()));&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    using (KeyedHashAlgorithm alg = HMACSHA1.Create())&lt;br /&gt;    {&lt;br /&gt;        //according to http://oauth.googlecode.com/svn/spec/core/1.0/oauth-core-1_0.html#rfc.section.9.2 we should concat [Consumer Secret] + &amp; + [Token Secrect]. The latter one is not provided by MySpace. So we imply empty string in this place.&lt;br /&gt;        alg.Key = Encoding.ASCII.GetBytes(secretKey + "&amp;");&lt;br /&gt;&lt;br /&gt;        byte[] dataBuffer = Encoding.ASCII.GetBytes(@base.ToString());&lt;br /&gt;        byte[] hashBytes = alg.ComputeHash(dataBuffer);&lt;br /&gt;&lt;br /&gt;        return Convert.ToBase64String(hashBytes);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;There is no reason to use the UrlEncode as delegate except placing it in a single method for readability of this post.&lt;br /&gt;&lt;br /&gt;After comparing signature out of 'oauth_signature' query string parameter and the one the method above returns you can also verify auth timestamp to be up to date:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: c#"&gt;private const string _oauthTimestampKey = "oauth_timestamp";&lt;br /&gt;private static readonly TimeSpan _staledInterval = TimeSpan.FromMinutes(10);&lt;br /&gt;private static readonly DateTime _stDate = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;long authTime;&lt;br /&gt;if (!Int64.TryParse(request.QueryString[_oauthTimestampKey], NumberStyles.Any, CultureInfo.InvariantCulture, out authTime))&lt;br /&gt;{&lt;br /&gt;    #region Logging&lt;br /&gt;    if (_log.IsDebugEnabled) _log.DebugFormat("Couldn't parse oauth_timestamp value {0}", authTime);&lt;br /&gt;    #endregion&lt;br /&gt;    return false;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;var now = DateTime.UtcNow;&lt;br /&gt;DateTime time = _stDate.AddSeconds(authTime);&lt;br /&gt;if (now - time &amp;gt; _staledInterval)&lt;br /&gt;{&lt;br /&gt;    #region Logging&lt;br /&gt;    if (_log.IsDebugEnabled) _log.DebugFormat("Auth time was too late. Expected greater than {0}. Actual was {1}", now - _staledInterval, time);&lt;br /&gt;    #endregion&lt;br /&gt;    return false;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/938730668763769016-7241454047977489680?l=www.borisbyk.com' alt='' /&gt;&lt;/div&gt;</description><link>http://www.borisbyk.com/2009/08/how-to-check-signature-in-myspace.html</link><author>noreply@blogger.com (Boris Byk)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-938730668763769016.post-938298825150866401</guid><pubDate>Thu, 11 Jun 2009 03:05:00 +0000</pubDate><atom:updated>2012-01-23T23:30:33.309-08:00</atom:updated><title>How to run a shell command in the background on windows</title><description>&lt;div&gt;&lt;p&gt;If you are dealing wih unix os you can run command in background merely adding &amp;amp; in shell:&lt;/p&gt;&lt;table width="100%" cellspacing="0" cellpadding="1" border="0" style="BACKGROUND:#fffadb"&gt;&lt;tbody&gt;&lt;tr&gt;             &lt;td&gt;sleep 2 &amp;amp;&lt;/td&gt;         &lt;/tr&gt;&lt;/tbody&gt; &lt;/table&gt;&lt;p style="MARGIN-TOP:10px"&gt;Recently I did need this functionality as I was debugging a web application crashes on our live servers. Being in terminal session I run the &lt;a href="http://www.microsoft.com/whdc/devtools/debugging/default.mspx" target="_blank"&gt;adplus&lt;/a&gt; script to catch crashes for a specified process:&lt;/p&gt;&lt;table width="100%" cellspacing="0" cellpadding="1" border="0" style="BACKGROUND:#fffadb"&gt;&lt;tbody&gt;&lt;tr&gt;             &lt;td&gt;adplus -crash -p &amp;lt;pid&amp;gt;&lt;/td&gt;         &lt;/tr&gt;&lt;/tbody&gt; &lt;/table&gt;&lt;p style="MARGIN-TOP:10px"&gt;The script attaches debugger to&amp;nbsp;a process making the debugger monitor exceptions. It&amp;nbsp;could take a long while till we catch anything. I needed to leave my terminal session unattended or&amp;nbsp;forcibly close it to proceed my regular routines. An unattended or disconnected session can be&amp;nbsp;logged out&amp;nbsp;according to a policy set by administrator, but&amp;nbsp;the running script stuck to my session.&lt;/p&gt;&lt;p&gt;Fortunately, windows users have the&amp;nbsp;magic '&lt;a href="http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/at.mspx?mfr=true" target="_blank"&gt;at&lt;/a&gt;' command that schedules commands at a specified time. So we can run our debugging script in the background just by passing it the scheduler:&lt;/p&gt;&lt;table width="100%" cellspacing="0" cellpadding="1" border="0" style="BACKGROUND:#fffadb"&gt;&lt;tbody&gt;&lt;tr&gt;             &lt;td&gt;at &amp;lt;time&amp;gt; cscript "&amp;lt;fullpath-to&amp;gt;\adplus.vbs" -quiet -crash -p &amp;lt;pid&amp;gt;&lt;/td&gt;         &lt;/tr&gt;&lt;/tbody&gt; &lt;/table&gt;&lt;p style="MARGIN-TOP:10px"&gt;We need the &lt;strong&gt;-quiet&lt;/strong&gt; option to skip initial dialog box the script shows when attaching a process. We use absolute path to the adplus because the current directory for the executing command is the systemroot folder.&amp;nbsp;Our command will be executed under &lt;a href="http://msdn.microsoft.com/en-us/library/ms684190(VS.85).aspx" target="_blank"&gt;System&lt;/a&gt; user. It's enough for debugging. But be careful when you rely on this, e.g. when you connect to sql server using integrated security.&lt;/p&gt;&lt;p&gt;I set the time parameter a minute ahead and the task is appointed on today.&lt;/p&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/938730668763769016-938298825150866401?l=www.borisbyk.com' alt='' /&gt;&lt;/div&gt;</description><link>http://www.borisbyk.com/2009/06/how-to-run-shell-command-in-background.html</link><author>noreply@blogger.com (Boris Byk)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-938730668763769016.post-2711786158687606707</guid><pubDate>Sat, 28 Mar 2009 03:04:00 +0000</pubDate><atom:updated>2012-01-24T09:27:02.638-08:00</atom:updated><title>DevSmtp server released</title><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div&gt;Have you ever debugged sending emails from your application? I have many times. Users of your website pay for goods and then they should be sent a notification. The conditions to test receiving mails can be uneasy. User account email should be valid and you are allowed to connect to smtp server or have your local smtp that might be considered by the remote one as unreliable and your mail will be rejected or cut off by a spam filter.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As a developer I always wanted a reliable tool for checking the both things: to ensure the email is sent and see how the email looks like for user.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Besides Windows Vista doesn't have&amp;nbsp;an smtp server. So I decided to implement it on my own. It wasn't a real world project and I&amp;nbsp;didn't have&amp;nbsp;tight schedule, so I chose to refresh my C++ skills that had been more&amp;nbsp;academical than practical and to write a server using &lt;a href="http://msdn.microsoft.com/en-us/library/aa365198(VS.85).aspx" target="_blank"&gt;I/O Completion Ports&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I use &lt;a href="https://github.com/"&gt;github&lt;/a&gt;&amp;nbsp;to host the &lt;a href="http://bitbucket.org/bbyk/devsmtp/wiki/Home" target="_blank"&gt;project&lt;/a&gt;. There you can either download the project source code and compile it in VS 2008 or get a precompiled binary.&lt;ol&gt;&lt;li&gt;In order to run&amp;nbsp;in console mode&amp;nbsp;put &lt;strong&gt;devsmtp.exe&lt;/strong&gt; in an appropriate location and execute: &lt;em&gt;devsmtp -c&lt;/em&gt;&lt;/li&gt;&lt;li&gt;to register&amp;nbsp;as windows service, execute: &lt;em&gt;devsmtp -i &lt;/em&gt;(to uninstall, use &lt;em&gt;devsmtp -u&lt;/em&gt;)&lt;/li&gt;&lt;/ol&gt;Now start testing you programs. If you want to verify a message is sent, run &lt;a href="http://technet.microsoft.com/en-us/sysinternals/bb896647.aspx" target="_blank"&gt;DebugView&lt;/a&gt; utility and you will see smtp communication protocol messages between your application and the server. After the message is on the server, it will be stored in a folder under &lt;strong&gt;devsmtp.exe&lt;/strong&gt; location&amp;nbsp;named with &lt;em&gt;from email.&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;So you can double click on the eml file and see it in embedded viewer.&lt;br /&gt;&lt;br /&gt;Attention. The server doesn't send mails to recipients. It serves for the debugging purpose only.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Have fun!&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/938730668763769016-2711786158687606707?l=www.borisbyk.com' alt='' /&gt;&lt;/div&gt;</description><link>http://www.borisbyk.com/2009/03/devsmtp-server-released.html</link><author>noreply@blogger.com (Boris Byk)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-938730668763769016.post-3827115994471862188</guid><pubDate>Wed, 28 Jan 2009 04:02:00 +0000</pubDate><atom:updated>2012-01-23T23:32:35.069-08:00</atom:updated><title>How to fix Windows SDK Configuration Tool</title><description>&lt;div&gt;&lt;p&gt;There are many posts out there pointing out that &lt;font face="Arial"&gt;&lt;a href="http://blogs.msdn.com/windowssdk/archive/2008/03/01/integrating-windows-sdk-and-vs-with-new-sdk-configuration-tool.aspx" target="_blank"&gt;Windows SDK Configuration Tool&lt;/a&gt;&amp;nbsp;contains a bug. When I first met the &lt;a href="http://social.msdn.microsoft.com/Forums/en-US/windowssdk/thread/04c716ea-c2bb-4da5-aaaf-fa4fa103cc7f/" target="_blank"&gt;issue&lt;/a&gt; I googled hither and thither but did find a solution for Visual Studio 2005. The &lt;a href="http://blogs.msdn.com/windowssdk/archive/2008/06/30/winsdk-bug-notification-sdk-config-tool-appears-to-work-but-fails.aspx" target="_blank"&gt;workarounds&lt;/a&gt;&amp;nbsp;did not work for me and were too clumsy to use them on a regular basis.&lt;/font&gt;&lt;/p&gt;&lt;p&gt;Eventually I decided to dig into its code - fortunately &lt;font face="Arial"&gt;WindowsSdkVer.exe is a .net assembly. Therefore, bingo, we can use &lt;a href="http://en.wikipedia.org/wiki/.NET_Reflector" target="_blank"&gt;.net reflector&lt;/a&gt; to infer its sorce code. It wasn't too difficult. To that end, the reflector contains an option to export an entire&amp;nbsp;assembly as the visual studio project:&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;a href="http://borisbyk.com/blog/images/borisbyk_com/blog/1/r_export.gif" target="_blank"&gt;&lt;img width="120" border="0" height="120" src="http://borisbyk.com/blog/images/borisbyk_com/blog/1/t_export.gif" alt="Export an assembly"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The exported&amp;nbsp;&lt;font face="Arial"&gt;WindowsSdkVer &lt;/font&gt;project contained a dependency, the library VCIntegrate.dll, that can be found in the same folder as &lt;font face="Arial"&gt;WindowsSdkVer.exe itself lies. I added the library to the project references and could build and run it.&lt;/font&gt;&lt;/p&gt;&lt;p&gt;Running the project on my Vista x64 I quickly found my issue. It was in the Utility.cs file, the GetInstalledProduct method:&lt;/p&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-FAMILY:&amp;quot;Courier New&amp;quot;;COLOR:blue;FONT-SIZE:10pt"&gt;foreach&lt;/span&gt;&lt;span style="FONT-FAMILY:&amp;quot;Courier New&amp;quot;;FONT-SIZE:10pt"&gt; (&lt;span style="COLOR:blue"&gt;string&lt;/span&gt; &lt;span style="COLOR:#020002"&gt;str&lt;/span&gt; &lt;span style="COLOR:blue"&gt;in&lt;/span&gt; &lt;span style="COLOR:#020002"&gt;key&lt;/span&gt;.&lt;span style="COLOR:#020002"&gt;GetSubKeyNames&lt;/span&gt;())&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-FAMILY:&amp;quot;Courier New&amp;quot;;FONT-SIZE:10pt"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-FAMILY:&amp;quot;Courier New&amp;quot;;FONT-SIZE:10pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:#2b91af"&gt;RegistryKey&lt;/span&gt; &lt;span style="COLOR:#020002"&gt;key2&lt;/span&gt; = &lt;span style="COLOR:#020002"&gt;key&lt;/span&gt;.&lt;span style="COLOR:#020002"&gt;OpenSubKey&lt;/span&gt;(&lt;span style="COLOR:#020002"&gt;str&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-FAMILY:&amp;quot;Courier New&amp;quot;;FONT-SIZE:10pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:#2b91af"&gt;Product&lt;/span&gt; &lt;span style="COLOR:#020002"&gt;newProduct&lt;/span&gt; = &lt;span style="COLOR:blue"&gt;new&lt;/span&gt; &lt;span style="COLOR:#2b91af"&gt;Product&lt;/span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-FAMILY:&amp;quot;Courier New&amp;quot;;FONT-SIZE:10pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue"&gt;try&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-FAMILY:&amp;quot;Courier New&amp;quot;;FONT-SIZE:10pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-FAMILY:&amp;quot;Courier New&amp;quot;;FONT-SIZE:10pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:#020002"&gt;newProduct&lt;/span&gt;.&lt;span style="COLOR:#020002"&gt;SdkVersion&lt;/span&gt; = &lt;span style="COLOR:#020002"&gt;str&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-FAMILY:&amp;quot;Courier New&amp;quot;;FONT-SIZE:10pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue"&gt;if&lt;/span&gt; (!&lt;span style="COLOR:blue"&gt;string&lt;/span&gt;.&lt;span style="COLOR:#020002"&gt;IsNullOrEmpty&lt;/span&gt;(&lt;span style="COLOR:#020002"&gt;productVersionKey&lt;/span&gt;))&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-FAMILY:&amp;quot;Courier New&amp;quot;;FONT-SIZE:10pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-FAMILY:&amp;quot;Courier New&amp;quot;;FONT-SIZE:10pt"&gt;&lt;strike&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:#020002"&gt;newProduct&lt;/span&gt;.&lt;span style="COLOR:#020002"&gt;Version&lt;/span&gt; = &lt;span style="COLOR:blue"&gt;new&lt;/span&gt; &lt;span style="COLOR:#2b91af"&gt;Version&lt;/span&gt;(&lt;span style="COLOR:#020002"&gt;key2&lt;/span&gt;.&lt;span style="COLOR:#020002"&gt;GetValue&lt;/span&gt;(&lt;span style="COLOR:#020002"&gt;productVersionKey&lt;/span&gt;).&lt;span style="COLOR:#020002"&gt;ToString&lt;/span&gt;());&lt;/strike&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-FAMILY:&amp;quot;Courier New&amp;quot;;FONT-SIZE:10pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="COLOR:#020002"&gt;newProduct&lt;/span&gt;.&lt;span style="COLOR:#020002"&gt;Version&lt;/span&gt; = &lt;span style="COLOR:blue"&gt;new&lt;/span&gt; &lt;span style="COLOR:#2b91af"&gt;Version&lt;/span&gt;(&lt;span style="COLOR:#020002"&gt;key2&lt;/span&gt;.&lt;span style="COLOR:#020002"&gt;GetValue&lt;/span&gt;(&lt;span style="COLOR:#020002"&gt;productVersionKey&lt;/span&gt;).&lt;span style="COLOR:#020002"&gt;ToString&lt;/span&gt;().&lt;span style="COLOR:#020002"&gt;Replace&lt;/span&gt;(&lt;span style="COLOR:#a31515"&gt;"v"&lt;/span&gt;, &lt;span style="COLOR:#a31515"&gt;""&lt;/span&gt;).&lt;span style="COLOR:#020002"&gt;Replace&lt;/span&gt;(&lt;span style="COLOR:#a31515"&gt;"A"&lt;/span&gt;, &lt;span style="COLOR:#a31515"&gt;""&lt;/span&gt;));&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-FAMILY:&amp;quot;Courier New&amp;quot;;FONT-SIZE:10pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="FONT-FAMILY:&amp;quot;Courier New&amp;quot;;FONT-SIZE:10pt"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-FAMILY:&amp;quot;Courier New&amp;quot;;FONT-SIZE:10pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue"&gt;else&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-FAMILY:&amp;quot;Courier New&amp;quot;;FONT-SIZE:10pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/div&gt;&lt;p&gt;The problem is that the Version class can't parse version&amp;nbsp;given as the value of &lt;font face="Arial"&gt;&lt;strong&gt;v6.0A&lt;/strong&gt;&lt;/font&gt;&amp;nbsp;being in my windows registry under the following key: &lt;font face="Arial"&gt;HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432NODE\Microsoft\Microsoft SDKs\Windows\v6.0A\&lt;font face="Arial"&gt;ProductVersion.&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;Stripping leading and ending characters helped somehow. But the&amp;nbsp;code seemed to contain&amp;nbsp;various issues. The next one I met&amp;nbsp;was&amp;nbsp;in VersionSelector.cs, the GetInstalledVisualStudioVersions method:&lt;/p&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;strike&gt;&lt;span style="FONT-FAMILY:&amp;quot;Courier New&amp;quot;;COLOR:blue;FONT-SIZE:10pt"&gt;foreach&lt;/span&gt;&lt;span style="FONT-FAMILY:&amp;quot;Courier New&amp;quot;;FONT-SIZE:10pt"&gt; (&lt;span style="COLOR:#2b91af"&gt;Product&lt;/span&gt; &lt;span style="COLOR:#020002"&gt;product&lt;/span&gt; &lt;span style="COLOR:blue"&gt;in&lt;/span&gt; &lt;span style="COLOR:#020002"&gt;products&lt;/span&gt;)&lt;/span&gt;&lt;/strike&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-FAMILY:&amp;quot;Courier New&amp;quot;;COLOR:blue;FONT-SIZE:10pt"&gt;foreach&lt;/span&gt;&lt;span style="FONT-FAMILY:&amp;quot;Courier New&amp;quot;;FONT-SIZE:10pt"&gt; (&lt;span style="COLOR:#2b91af"&gt;Product&lt;/span&gt; &lt;span style="COLOR:#020002"&gt;product&lt;/span&gt; &lt;span style="COLOR:blue"&gt;in&lt;/span&gt; &lt;span style="COLOR:blue"&gt;new&lt;/span&gt; &lt;span style="COLOR:#2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="COLOR:#2b91af"&gt;Product&lt;/span&gt;&amp;gt;(&lt;span style="COLOR:#020002"&gt;products&lt;/span&gt;))&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-FAMILY:&amp;quot;Courier New&amp;quot;;FONT-SIZE:10pt"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-FAMILY:&amp;quot;Courier New&amp;quot;;FONT-SIZE:10pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue"&gt;float&lt;/span&gt; &lt;span style="COLOR:#020002"&gt;num&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-FAMILY:&amp;quot;Courier New&amp;quot;;FONT-SIZE:10pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue"&gt;if&lt;/span&gt; (&lt;span style="COLOR:blue"&gt;float&lt;/span&gt;.&lt;span style="COLOR:#020002"&gt;TryParse&lt;/span&gt;(&lt;span style="COLOR:#020002"&gt;product&lt;/span&gt;.&lt;span style="COLOR:#020002"&gt;SdkVersion&lt;/span&gt;, &lt;span style="COLOR:blue"&gt;out&lt;/span&gt; &lt;span style="COLOR:#020002"&gt;num&lt;/span&gt;))&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-FAMILY:&amp;quot;Courier New&amp;quot;;FONT-SIZE:10pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-FAMILY:&amp;quot;Courier New&amp;quot;;FONT-SIZE:10pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue"&gt;if&lt;/span&gt; (&lt;span style="COLOR:#020002"&gt;num&lt;/span&gt; &amp;lt; 8f)&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-FAMILY:&amp;quot;Courier New&amp;quot;;FONT-SIZE:10pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-FAMILY:&amp;quot;Courier New&amp;quot;;FONT-SIZE:10pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:#020002"&gt;products&lt;/span&gt;.&lt;span style="COLOR:#020002"&gt;Remove&lt;/span&gt;(&lt;span style="COLOR:#020002"&gt;product&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-FAMILY:&amp;quot;Courier New&amp;quot;;FONT-SIZE:10pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="FONT-FAMILY:&amp;quot;Courier New&amp;quot;;FONT-SIZE:10pt"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-FAMILY:&amp;quot;Courier New&amp;quot;;FONT-SIZE:10pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-FAMILY:&amp;quot;Courier New&amp;quot;;FONT-SIZE:10pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue"&gt;else&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-FAMILY:&amp;quot;Courier New&amp;quot;;FONT-SIZE:10pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-FAMILY:&amp;quot;Courier New&amp;quot;;FONT-SIZE:10pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:#020002"&gt;products&lt;/span&gt;.&lt;span style="COLOR:#020002"&gt;Remove&lt;/span&gt;(&lt;span style="COLOR:#020002"&gt;product&lt;/span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-FAMILY:&amp;quot;Courier New&amp;quot;;FONT-SIZE:10pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-FAMILY:&amp;quot;Courier New&amp;quot;;FONT-SIZE:10pt"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div style="MARGIN:0cm 0cm 10pt"&gt;&lt;span style="LINE-HEIGHT:115%;FONT-FAMILY:&amp;quot;Courier New&amp;quot;;COLOR:blue;FONT-SIZE:10pt"&gt;return&lt;/span&gt;&lt;span style="LINE-HEIGHT:115%;FONT-FAMILY:&amp;quot;Courier New&amp;quot;;FONT-SIZE:10pt"&gt; &lt;span style="COLOR:#020002"&gt;products&lt;/span&gt;;&lt;/span&gt;&lt;span style="FONT-FAMILY:&amp;quot;Courier New&amp;quot;;COLOR:blue;FONT-SIZE:10pt"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;p&gt;&lt;font face="Arial" color="#000000"&gt;Guess what a problem may raise up here?&amp;nbsp;Who did write this? &lt;img src="http://borisbyk.com/blog/Providers/BlogEntryEditor/FCKeditor/editor/images/smiley/msn/regular_smile.gif" alt=""&gt;&amp;nbsp;You can't delete from a collection during looking it through by enumerator.&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font face="Arial" color="#000000"&gt;And at last for those having a non-english windows you have to add a line into the Program.cs file:&lt;/font&gt;&lt;/p&gt;&lt;font face="Arial" color="#000000"&gt;&lt;br /&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-FAMILY:&amp;quot;Courier New&amp;quot;;FONT-SIZE:10pt"&gt;[&lt;span style="COLOR:#2b91af"&gt;STAThread&lt;/span&gt;]&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-FAMILY:&amp;quot;Courier New&amp;quot;;COLOR:blue;FONT-SIZE:10pt"&gt;private&lt;/span&gt;&lt;span style="FONT-FAMILY:&amp;quot;Courier New&amp;quot;;FONT-SIZE:10pt"&gt; &lt;span style="COLOR:blue"&gt;static&lt;/span&gt; &lt;span style="COLOR:blue"&gt;void&lt;/span&gt; &lt;span style="COLOR:#020002"&gt;Main&lt;/span&gt;(&lt;span style="COLOR:blue"&gt;string&lt;/span&gt;[] &lt;span style="COLOR:#020002"&gt;args&lt;/span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-FAMILY:&amp;quot;Courier New&amp;quot;;FONT-SIZE:10pt"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-FAMILY:&amp;quot;Courier New&amp;quot;;FONT-SIZE:10pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;span style="COLOR:#2b91af"&gt;Thread&lt;/span&gt;.&lt;span style="COLOR:#020002"&gt;CurrentThread&lt;/span&gt;.&lt;span style="COLOR:#020002"&gt;CurrentCulture&lt;/span&gt; = &lt;span style="COLOR:#2b91af"&gt;CultureInfo&lt;/span&gt;.&lt;span style="COLOR:#020002"&gt;InvariantCulture&lt;/span&gt;;&lt;/strong&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&amp;nbsp;&lt;/div&gt;&lt;div style="MARGIN:0cm 0cm 10pt"&gt;&lt;span style="LINE-HEIGHT:115%;FONT-FAMILY:&amp;quot;Courier New&amp;quot;;FONT-SIZE:10pt"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="LINE-HEIGHT:115%;FONT-FAMILY:&amp;quot;Courier New&amp;quot;;COLOR:#2b91af;FONT-SIZE:10pt"&gt;Mutex&lt;/span&gt;&lt;span style="LINE-HEIGHT:115%;FONT-FAMILY:&amp;quot;Courier New&amp;quot;;FONT-SIZE:10pt"&gt; &lt;span style="COLOR:#020002"&gt;mutex&lt;/span&gt; = &lt;span style="COLOR:blue"&gt;null&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/font&gt;&lt;br /&gt;&lt;p&gt;&lt;font face="Arial" color="#000000"&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font face="Arial" color="#000000"&gt;&lt;font face="Arial"&gt;It is required to parse numbers correctly.&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font face="Arial" color="#000000"&gt;&lt;font face="Arial"&gt;You should place the compiled execution over the existing one to ensure that all its functionallity works properly. That because the program relies on files lying around.&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font face="Arial" color="#000000"&gt;&lt;font face="Arial"&gt;If you somehow trust me, you can download the &lt;a href="http://borisbyk.com/blog/images/borisbyk_com/blog/1/WindowsSdkVerPatched.zip" target="_blank"&gt;patched utility&lt;/a&gt; directly.&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/938730668763769016-3827115994471862188?l=www.borisbyk.com' alt='' /&gt;&lt;/div&gt;</description><link>http://www.borisbyk.com/2009/01/how-to-fix-windows-sdk-configuration.html</link><author>noreply@blogger.com (Boris Byk)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-938730668763769016.post-7576285299069792769</guid><pubDate>Tue, 30 Dec 2008 04:00:00 +0000</pubDate><atom:updated>2012-01-23T23:43:16.185-08:00</atom:updated><title>How to encrypt/decrypt with passphrase</title><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div&gt;I was stuck with this when I started using IIS7's &lt;a href="http://technet.microsoft.com/en-us/library/cc772200.aspx"&gt;AppCmd&lt;/a&gt; utility. The utility allows to export and import appication pool configuration, while not having an option to encode/decode identity password. But it was required to store the configuration under the source control system. So I decided to write a simple command-line encoding/decoding utility for a particular section being fetched by regular expression.&lt;br /&gt;&lt;br /&gt;I use a symmetric algorithm because key is defined with passphrase for both encoding and decoding operations. Creating key from passphrase is based on hashing. We are required to have keys with fixed length and character sets, thus hashing goes a long way here&lt;span style="color: black;"&gt;:&lt;/span&gt;&lt;br /&gt;&lt;pre class="brush: c#"&gt;var bytes = Encoding.Unicode.GetBytes(passphrase);&lt;br /&gt;var key = SHA256Managed.Create().ComputeHash(bytes);&lt;br /&gt;var iv = MD5.Create().ComputeHash(bytes);&lt;br /&gt;&lt;/pre&gt;Key and vector may have different requirements regarding length of byte arrays. For the RijndaelManaged class they are 32 and 16 respectively. Thus I use SHA256 and MD5 algorithms to get keys with the appropriate length.&lt;pre class="brush: c#"&gt;var alg = SymmetricAlgorithm.Create();&lt;br /&gt;var ms = new MemoryStream();&lt;br /&gt;var buffer = Encoding.Unicode.GetBytes(text);&lt;br /&gt; &lt;br /&gt;using (var enc = new CryptoStream(&lt;br /&gt;    ms, alg.CreateEncryptor(key, iv),&lt;br /&gt;    CryptoStreamMode.Write&lt;br /&gt;))&lt;br /&gt;{&lt;br /&gt;    enc.Write(buffer, 0, buffer.Length);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;The code above feeds the entire text to the CryptoStream. For passwords encoding it shouldn't be a perfomance issue. Decoding has quite similar implementation. Rather than using alg.CreateEncryptor it should use alg.CreateDecryptor there.&lt;br /&gt;&lt;span style="font-size: 10pt;"&gt;&lt;span style="color: blue; font-size: 10pt;"&gt;&lt;span style="font-size: 10pt;"&gt;&lt;span style="font-size: 10pt;"&gt;&lt;span style="font-size: 10pt;"&gt;&lt;span style="color: blue; font-size: 10pt;"&gt;&lt;span style="color: #020002;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="line-height: normal;"&gt;&lt;div style="line-height: normal;"&gt;&lt;div style="line-height: normal;"&gt;&lt;div style="line-height: normal;"&gt;&lt;span style="color: #020002;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="line-height: normal;"&gt;&lt;br /&gt;&lt;span style="color: #020002;"&gt;Additionally I use a couple of extention methods to format byte array to hexadecimal string and vice versa. Here are the entire Encode/Decode methods implementation and the helper methods:&lt;/span&gt;&lt;/div&gt;&lt;div style="line-height: normal;"&gt;&lt;/div&gt;&lt;div style="line-height: normal;"&gt;&lt;span style="color: #020002;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="line-height: normal;"&gt;&lt;span style="color: #020002;"&gt;&lt;br /&gt;&lt;pre class="brush: c#"&gt;private static string Encode(string text, string passphrase)&lt;br /&gt;{&lt;br /&gt;    var bytes = Encoding.Unicode.GetBytes(passphrase);&lt;br /&gt;    var key = SHA256Managed.Create().ComputeHash(bytes);&lt;br /&gt;    var iv = MD5.Create().ComputeHash(bytes);&lt;br /&gt; &lt;br /&gt;    var alg = SymmetricAlgorithm.Create();&lt;br /&gt;    var ms = new MemoryStream();&lt;br /&gt;    var buffer = Encoding.Unicode.GetBytes(text);&lt;br /&gt; &lt;br /&gt;    using(var enc = new CryptoStream(&lt;br /&gt;        ms, alg.CreateEncryptor(key, iv),&lt;br /&gt;        CryptoStreamMode.Write&lt;br /&gt;    )) enc.Write(buffer, 0, buffer.Length);&lt;br /&gt; &lt;br /&gt;    return ms.ToArray().ToHexString();&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;private static string Decode(string text, string passphrase)&lt;br /&gt;{           &lt;br /&gt;    var bytes = Encoding.Unicode.GetBytes(passphrase);&lt;br /&gt;    var key = SHA256Managed.Create().ComputeHash(bytes);&lt;br /&gt;    var iv = MD5.Create().ComputeHash(bytes);&lt;br /&gt; &lt;br /&gt;    var alg = SymmetricAlgorithm.Create();&lt;br /&gt;    var ms = new MemoryStream();&lt;br /&gt; &lt;br /&gt;    var buffer = text.ToByteArray();&lt;br /&gt; &lt;br /&gt;    try&lt;br /&gt;    {&lt;br /&gt;        using (var enc = new CryptoStream(&lt;br /&gt;            ms, alg.CreateDecryptor(key, iv),&lt;br /&gt;            CryptoStreamMode.Write&lt;br /&gt;        )) enc.Write(buffer, 0, buffer.Length);&lt;br /&gt;    }&lt;br /&gt;    catch (Exception)&lt;br /&gt;    {&lt;br /&gt;        Console.Error.WriteLine("Error: wrong passphrase.");&lt;br /&gt;        Environment.Exit(2);&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    return Encoding.Unicode.GetString(ms.ToArray());&lt;br /&gt;}&lt;br /&gt;...&lt;br /&gt;internal static string ToHexString(this byte[] bytes)&lt;br /&gt;{&lt;br /&gt;    StringBuilder builder = new StringBuilder(3 * bytes.Length);&lt;br /&gt; &lt;br /&gt;    for (int i = 0; i &lt; bytes.Length; i++)&lt;br /&gt;    {&lt;br /&gt;        builder.AppendFormat("{0:x2}", bytes[i]);&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    return builder.ToString().ToLowerInvariant();&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;internal static byte[] ToByteArray(this string hexString)&lt;br /&gt;{&lt;br /&gt;    byte[] buffer = new byte[hexString.Length / 2];&lt;br /&gt; &lt;br /&gt;    for (int i = 0; i &lt; hexString.Length; i += 2)&lt;br /&gt;    {&lt;br /&gt;        buffer[i / 2] = byte.Parse(hexString.Substring(i, 2), NumberStyles.HexNumber);&lt;br /&gt;    }&lt;br /&gt;   &lt;br /&gt;    return buffer;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/938730668763769016-7576285299069792769?l=www.borisbyk.com' alt='' /&gt;&lt;/div&gt;</description><link>http://www.borisbyk.com/2008/12/how-to-encryptdecrypt-with-passphrase.html</link><author>noreply@blogger.com (Boris Byk)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-938730668763769016.post-5752505381541912803</guid><pubDate>Wed, 10 Dec 2008 03:57:00 +0000</pubDate><atom:updated>2012-01-23T23:32:00.223-08:00</atom:updated><title>How to add support for Google Chrome in ASP.NET</title><description>&lt;div&gt;&lt;p&gt;Do you like &lt;a href="http://www.google.com/chrome" target="_blank"&gt;Google Chrome&lt;/a&gt;? I do, especially after they &lt;a href="http://www.theregister.co.uk/2008/09/03/google_chrome_eula_sucks/" target="_blank"&gt;amended&lt;/a&gt; the &lt;font face="Arial"&gt;section 11.4 of the&lt;/font&gt;&amp;nbsp;EULA &lt;img src="http://borisbyk.com/blog/Providers/BlogEntryEditor/FCKeditor/editor/images/smiley/msn/regular_smile.gif" alt=""&gt;.&amp;nbsp;&lt;/p&gt;&lt;p&gt;Then what about adding browser capabilities for the browser in ASP.NET. It is better not to modify the browser&amp;nbsp;definition files under the&amp;nbsp;&amp;nbsp;&lt;em&gt;&amp;lt;windir&amp;gt;\Microsoft.NET\Framework\&amp;lt;ver&amp;gt;\CONFIG\Browsers &lt;/em&gt;folder since they can be changed&amp;nbsp;in a next .net framework&amp;nbsp;release or&amp;nbsp;service pack. Just add a &lt;em&gt;.browser&lt;/em&gt; file to your web project under the &lt;em&gt;App_Browser&lt;/em&gt; folder.&lt;/p&gt;&lt;p&gt;&lt;img width="188" height="111" src="http://borisbyk.com/blog/images/borisbyk_com/blog/1/r_App_Browsers.gif" alt=""&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;Here is the content of the file:&lt;/p&gt;&lt;table width="100%" cellspacing="1" cellpadding="15" border="0"&gt;&lt;tbody&gt;&lt;tr&gt;             &lt;td&gt;&lt;br /&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New'"&gt;&amp;lt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#a31515;FONT-FAMILY:'Courier New'"&gt;browsers&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New'"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New'"&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#a31515;FONT-FAMILY:'Courier New'"&gt;browser &lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:red;FONT-FAMILY:'Courier New'"&gt;id&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New'"&gt;=&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New'"&gt;"&lt;span style="COLOR:blue"&gt;GoogleChrome&lt;/span&gt;" &lt;span style="COLOR:red"&gt;parentID&lt;/span&gt;&lt;span style="COLOR:blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR:blue"&gt;Safari1Plus&lt;/span&gt;"&lt;span style="COLOR:blue"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#a31515;FONT-FAMILY:'Courier New'"&gt;identification&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New'"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#a31515;FONT-FAMILY:'Courier New'"&gt;userAgent &lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:red;FONT-FAMILY:'Courier New'"&gt;match&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New'"&gt;=&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New'"&gt;"&lt;span style="COLOR:blue"&gt;Chrome/(?'version'(?'major'\d+)\.(?'minor'\d+\.\d+).\d+)&lt;/span&gt;"&lt;span style="COLOR:blue"&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#a31515;FONT-FAMILY:'Courier New'"&gt;identification&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New'"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#a31515;FONT-FAMILY:'Courier New'"&gt;capture&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New'"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#a31515;FONT-FAMILY:'Courier New'"&gt;capture&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New'"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#a31515;FONT-FAMILY:'Courier New'"&gt;capabilities&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New'"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#a31515;FONT-FAMILY:'Courier New'"&gt;capability &lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:red;FONT-FAMILY:'Courier New'"&gt;name&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New'"&gt;=&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New'"&gt;"&lt;span style="COLOR:blue"&gt;browser&lt;/span&gt;"&lt;span style="COLOR:blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR:red"&gt;value&lt;/span&gt;&lt;span style="COLOR:blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR:blue"&gt;Chrome&lt;/span&gt;"&lt;span style="COLOR:blue"&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#a31515;FONT-FAMILY:'Courier New'"&gt;capability &lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:red;FONT-FAMILY:'Courier New'"&gt;name&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New'"&gt;=&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New'"&gt;"&lt;span style="COLOR:blue"&gt;majorversion&lt;/span&gt;"&lt;span style="COLOR:blue"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR:red"&gt;value&lt;/span&gt;&lt;span style="COLOR:blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR:blue"&gt;${major}&lt;/span&gt;"&lt;span style="COLOR:blue"&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#a31515;FONT-FAMILY:'Courier New'"&gt;capability &lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:red;FONT-FAMILY:'Courier New'"&gt;name&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New'"&gt;=&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New'"&gt;"&lt;span style="COLOR:blue"&gt;minorversion&lt;/span&gt;"&lt;span style="COLOR:blue"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR:red"&gt;value&lt;/span&gt;&lt;span style="COLOR:blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR:blue"&gt;${minor}&lt;/span&gt;"&lt;span style="COLOR:blue"&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#a31515;FONT-FAMILY:'Courier New'"&gt;capability &lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:red;FONT-FAMILY:'Courier New'"&gt;name&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New'"&gt;=&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New'"&gt;"&lt;span style="COLOR:blue"&gt;version&lt;/span&gt;"&lt;span style="COLOR:blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR:red"&gt;value&lt;/span&gt;&lt;span style="COLOR:blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR:blue"&gt;${version}&lt;/span&gt;"&lt;span style="COLOR:blue"&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New'"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#a31515;FONT-FAMILY:'Courier New'"&gt;capabilities&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New'"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New'"&gt;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#a31515;FONT-FAMILY:'Courier New'"&gt;browser&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New'"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="MARGIN:0cm 0cm 10pt"&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;LINE-HEIGHT:115%;FONT-FAMILY:'Courier New'"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#a31515;LINE-HEIGHT:115%;FONT-FAMILY:'Courier New'"&gt;browsers&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;LINE-HEIGHT:115%;FONT-FAMILY:'Courier New'"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;         &lt;/tr&gt;&lt;/tbody&gt; &lt;/table&gt;&lt;p&gt;When I had done it, I found that it appeared a strange behavior. First starting the site in the Chrome made it stick with the Chrome definition for Apple Safari and vise versa.&lt;/p&gt;&lt;p&gt;After playing around with different variations of the above config I decided to stop wasting my time on it and to find how&amp;nbsp;ASP.NET caches the browser capabilities using a &lt;a href="http://reflector.red-gate.com" target="_blank"&gt;reflector&lt;/a&gt;. The code of all this&amp;nbsp;is pretty easy. The framework uses the User-Agent request-header as a cache key trimming its length by a configurable &lt;a href="http://msdn.microsoft.com/en-us/library/sk9az15a.aspx" target="_blank"&gt;parameter&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;span style="FONT-SIZE:10pt;LINE-HEIGHT:115%;FONT-FAMILY:'Courier New'"&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New'"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;table width="100%" cellspacing="1" cellpadding="15" border="0"&gt;&lt;tbody&gt;&lt;tr&gt;             &lt;td&gt;&amp;nbsp;&lt;br /&gt;&lt;div style="LINE-HEIGHT:normal"&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New'"&gt;&amp;lt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#a31515;FONT-FAMILY:'Courier New'"&gt;system.web&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New'"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="MARGIN:0cm 0cm 10pt"&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;LINE-HEIGHT:115%;FONT-FAMILY:'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#a31515;LINE-HEIGHT:115%;FONT-FAMILY:'Courier New'"&gt;browserCaps &lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:red;LINE-HEIGHT:115%;FONT-FAMILY:'Courier New'"&gt;userAgentCacheKeyLength&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;LINE-HEIGHT:115%;FONT-FAMILY:'Courier New'"&gt;=&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;LINE-HEIGHT:115%;FONT-FAMILY:'Courier New'"&gt;"&lt;span style="COLOR:blue"&gt;128&lt;/span&gt;"&lt;span style="COLOR:blue"&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;         &lt;/tr&gt;&lt;/tbody&gt; &lt;/table&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;I extended the value up to 128 from its default of 64 because the Chrome's user-agent string length is 118.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/938730668763769016-5752505381541912803?l=www.borisbyk.com' alt='' /&gt;&lt;/div&gt;</description><link>http://www.borisbyk.com/2008/12/how-to-add-support-for-google-chrome-in.html</link><author>noreply@blogger.com (Boris Byk)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-938730668763769016.post-7207431032555001405</guid><pubDate>Wed, 10 Dec 2008 03:52:00 +0000</pubDate><atom:updated>2012-01-23T23:54:49.084-08:00</atom:updated><title>.net structures performance tips and tricks</title><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div&gt;&lt;div class="item-body"&gt;&lt;div&gt;Recently I dug into clr structure performance and found it's rather funny. Some revelations were new to me.&lt;br /&gt;&lt;br /&gt;At first. If you have a structure containing two boolean fields, it is five times faster than structure containing three boolean fields, but it is equal to four boolean fields one! I merely return structure from method several million times and capture elapsed time by Stopwatcher (it is common scenario when we pass structure to method or return from it):&lt;/div&gt;&lt;pre class="brush: c#"&gt;public struct TestStruct&lt;br /&gt;{&lt;br /&gt;    public bool Field1;&lt;br /&gt;    public bool Field2;&lt;br /&gt;    public bool Field3;&lt;br /&gt;    public bool Field4;&lt;br /&gt;&lt;br /&gt;    public static TestStruct CreateNew()&lt;br /&gt;    {&lt;br /&gt;        return default(TestStruct);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;static void Main(string[] args)&lt;br /&gt;{&lt;br /&gt;    const int iterations = 50000000;&lt;br /&gt;    var sw = Stopwatch.StartNew();&lt;br /&gt;&lt;br /&gt;    for (int i = 0; i &amp;lt; iterations; i++)&lt;br /&gt;    {&lt;br /&gt;        var a = TestStruct.CreateNew();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    sw.Stop();&lt;br /&gt;    Console.WriteLine("elapsed {0} ms", sw.ElapsedMilliseconds);&lt;br /&gt;    Console.ReadKey();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;It seems like it depends on how optimal structure layout is for clr. A boolean field takes one byte. Let's add one more boolean field (fifth). Now we have the five times slump again. But, if we add one more boolean field (sixth), we have the same loss in performance. Seventh such field makes performance seven times slower :).&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Conclusion&lt;/b&gt;:&amp;nbsp;&lt;u&gt;the optimal structure size&amp;nbsp;values&amp;nbsp;are 1, 2, 4, 8&lt;/u&gt;. Let's take a look at another example:&lt;br /&gt;&lt;br /&gt;&lt;table border="1" cellpadding="0" cellspacing="0" style="border-bottom: medium none; border-collapse: collapse; border-left: medium none; border-right: medium none; border-top: medium none;"&gt;&lt;tbody&gt;&lt;tr&gt;             &lt;td style="background-color: transparent; border-bottom: black 1pt solid; border-left: black 1pt solid; border-right: black 1pt solid; border-top: black 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0cm; width: 247.6pt;" valign="top" width="330"&gt;&lt;br /&gt;&lt;div style="line-height: normal; margin: 0cm 0cm 0pt;"&gt;&lt;span lang="EN-US" style="color: blue; font-family: 'Courier New'; font-size: 10pt;"&gt;public&lt;/span&gt;&lt;span lang="EN-US" style="font-family: 'Courier New'; font-size: 10pt;"&gt; &lt;span style="color: blue;"&gt;bool&lt;/span&gt; &lt;span style="color: #020002;"&gt;Field1&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div style="line-height: normal; margin: 0cm 0cm 0pt;"&gt;&lt;span lang="EN-US" style="color: blue; font-family: 'Courier New'; font-size: 10pt;"&gt;public&lt;/span&gt;&lt;span lang="EN-US" style="font-family: 'Courier New'; font-size: 10pt;"&gt; &lt;span style="color: blue;"&gt;bool&lt;/span&gt; &lt;span style="color: #020002;"&gt;Field2&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div style="line-height: normal; margin: 0cm 0cm 0pt;"&gt;&lt;span lang="EN-US" style="color: blue; font-family: 'Courier New'; font-size: 10pt;"&gt;public&lt;/span&gt;&lt;span lang="EN-US" style="font-family: 'Courier New'; font-size: 10pt;"&gt; &lt;span style="color: blue;"&gt;bool&lt;/span&gt; &lt;span style="color: #020002;"&gt;Field3&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div style="line-height: normal; margin: 0cm 0cm 0pt;"&gt;&lt;span lang="EN-US" style="color: blue; font-family: 'Courier New'; font-size: 10pt;"&gt;public&lt;/span&gt;&lt;span lang="EN-US" style="font-family: 'Courier New'; font-size: 10pt;"&gt; &lt;span style="color: blue;"&gt;bool&lt;/span&gt; &lt;span style="color: #020002;"&gt;Field4&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div style="line-height: normal; margin: 0cm 0cm 0pt;"&gt;&lt;span lang="EN-US" style="color: blue; font-family: 'Courier New'; font-size: 10pt;"&gt;public&lt;/span&gt;&lt;span lang="EN-US" style="font-family: 'Courier New'; font-size: 10pt;"&gt; &lt;span style="color: blue;"&gt;bool&lt;/span&gt; &lt;span style="color: #020002;"&gt;Field5&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div style="line-height: normal; margin: 0cm 0cm 0pt;"&gt;&lt;span lang="EN-US" style="color: blue; font-family: 'Courier New'; font-size: 10pt;"&gt;public&lt;/span&gt;&lt;span lang="EN-US" style="font-family: 'Courier New'; font-size: 10pt;"&gt; &lt;span style="color: blue;"&gt;short&lt;/span&gt; &lt;span style="color: #020002;"&gt;Field6&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div style="line-height: normal; margin: 0cm 0cm 0pt;"&gt;&lt;span style="color: blue; font-family: 'Courier New'; font-size: 10pt;"&gt;public&lt;/span&gt;&lt;span style="font-family: 'Courier New'; font-size: 10pt;"&gt; &lt;span style="color: blue;"&gt;bool&lt;/span&gt; &lt;span style="color: #020002;"&gt;Field7&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div style="line-height: normal; margin: 0cm 0cm 0pt;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;/td&gt;             &lt;td style="background-color: transparent; border-bottom: black 1pt solid; border-left-color: #f0f0f0; border-right: black 1pt solid; border-top: black 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; padding-top: 0cm; width: 247.65pt;" valign="top" width="330"&gt;&lt;br /&gt;&lt;div style="line-height: normal; margin: 0cm 0cm 0pt;"&gt;&lt;span lang="EN-US" style="color: blue; font-family: 'Courier New'; font-size: 10pt;"&gt;public&lt;/span&gt;&lt;span lang="EN-US" style="font-family: 'Courier New'; font-size: 10pt;"&gt; &lt;span style="color: blue;"&gt;short&lt;/span&gt; &lt;span style="color: #020002;"&gt;Field1&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div style="line-height: normal; margin: 0cm 0cm 0pt;"&gt;&lt;span lang="EN-US" style="color: blue; font-family: 'Courier New'; font-size: 10pt;"&gt;public&lt;/span&gt;&lt;span lang="EN-US" style="font-family: 'Courier New'; font-size: 10pt;"&gt; &lt;span style="color: blue;"&gt;bool&lt;/span&gt; &lt;span style="color: #020002;"&gt;Field2&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div style="line-height: normal; margin: 0cm 0cm 0pt;"&gt;&lt;span lang="EN-US" style="color: blue; font-family: 'Courier New'; font-size: 10pt;"&gt;public&lt;/span&gt;&lt;span lang="EN-US" style="font-family: 'Courier New'; font-size: 10pt;"&gt; &lt;span style="color: blue;"&gt;bool&lt;/span&gt; &lt;span style="color: #020002;"&gt;Field3&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div style="line-height: normal; margin: 0cm 0cm 0pt;"&gt;&lt;span lang="EN-US" style="color: blue; font-family: 'Courier New'; font-size: 10pt;"&gt;public&lt;/span&gt;&lt;span lang="EN-US" style="font-family: 'Courier New'; font-size: 10pt;"&gt; &lt;span style="color: blue;"&gt;bool&lt;/span&gt; &lt;span style="color: #020002;"&gt;Field4&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div style="line-height: normal; margin: 0cm 0cm 0pt;"&gt;&lt;span lang="EN-US" style="color: blue; font-family: 'Courier New'; font-size: 10pt;"&gt;public&lt;/span&gt;&lt;span lang="EN-US" style="font-family: 'Courier New'; font-size: 10pt;"&gt; &lt;span style="color: blue;"&gt;bool&lt;/span&gt; &lt;span style="color: #020002;"&gt;Field5&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div style="line-height: normal; margin: 0cm 0cm 0pt;"&gt;&lt;span lang="EN-US" style="color: blue; font-family: 'Courier New'; font-size: 10pt;"&gt;public&lt;/span&gt;&lt;span lang="EN-US" style="font-family: 'Courier New'; font-size: 10pt;"&gt; &lt;span style="color: blue;"&gt;bool&lt;/span&gt; &lt;span style="color: #020002;"&gt;Field6&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;div style="line-height: normal; margin: 0cm 0cm 0pt;"&gt;&lt;span style="color: blue; font-family: 'Courier New'; font-size: 10pt;"&gt;public&lt;/span&gt;&lt;span style="font-family: 'Courier New'; font-size: 10pt;"&gt; &lt;span style="color: blue;"&gt;bool&lt;/span&gt; &lt;span style="color: #020002;"&gt;Field&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US" style="color: #020002; font-family: 'Courier New'; font-size: 10pt;"&gt;7&lt;/span&gt;&lt;span style="font-family: 'Courier New'; font-size: 10pt;"&gt;;&lt;/span&gt;&lt;span lang="EN-US" style="color: blue; font-family: 'Courier New'; font-size: 10pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;         &lt;/tr&gt;&lt;/tbody&gt; &lt;/table&gt;&lt;br /&gt;The structure fields&amp;nbsp;ordering from the first column four times slower than from the second. It seems it is because Field6&amp;nbsp;allocation starts from an&amp;nbsp;uneven byte 5. &lt;b&gt;Conclusion&lt;/b&gt;: &lt;u&gt;field starting byte should be even if the field takes more than one byte&lt;/u&gt;.&lt;br /&gt;&lt;br /&gt;The structure from our last example has eight bytes size and it's equal to a single long type allocation in memory. What if we create a 9 bytes size structure. Yes, it would be slowly and it is four times slowly. But the even and uneven allocation rules are still correct and can hit performace in approximately 2 times.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;Can we make up more generalize conclusion? I think so. If we create a structure with a single long type field and then will add one more long field and then one more we will see that we have approximately arithmetical progression in growth of elapsed intereval for our loop. Conclusion: the less structure the better. Difference between one and two longs allocation is highest: five times, but then it becomes less and less for 2 vs 3, 3 vs 4 long type fields structures.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;Comparing a simple class object creation time with 2 long type fields structure shows that such the structure is still 3 times faster. But a six long type fields structure creation time is approximately equal to that of the class.&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/938730668763769016-7207431032555001405?l=www.borisbyk.com' alt='' /&gt;&lt;/div&gt;</description><link>http://www.borisbyk.com/2008/12/net-structures-performance-tips-and.html</link><author>noreply@blogger.com (Boris Byk)</author><thr:total>0</thr:total></item></channel></rss>
