<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Thargy.com</title>
	<atom:link href="https://thargy.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://thargy.com</link>
	<description>Blogs and articles by Craig Dean</description>
	<lastBuildDate>Wed, 13 Oct 2021 19:59:10 +0000</lastBuildDate>
	<language>en-GB</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>

<image>
	<url>https://i0.wp.com/thargy.com/wp-content/uploads/2013/08/iphone_logo.png?fit=32%2C32&#038;ssl=1</url>
	<title>Thargy.com</title>
	<link>https://thargy.com</link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">34780165</site>	<item>
		<title>A note on the news</title>
		<link>https://thargy.com/2019/09/a-note-on-the-news/</link>
		
		<dc:creator><![CDATA[thargy]]></dc:creator>
		<pubDate>Tue, 24 Sep 2019 14:00:08 +0000</pubDate>
				<category><![CDATA[Management]]></category>
		<category><![CDATA[Personal]]></category>
		<category><![CDATA[Greta Thunberg]]></category>
		<category><![CDATA[Laterooms]]></category>
		<category><![CDATA[Malvern Group]]></category>
		<category><![CDATA[Stewardship]]></category>
		<category><![CDATA[Thomas Cook]]></category>
		<category><![CDATA[Whataboutism]]></category>
		<guid isPermaLink="false">https://thargy.com/?p=776</guid>

					<description><![CDATA[At some point, as business leaders, we have to stop looking towards tomorrow to fix the problems of our making.  Procrastination is not the painless solution it promises.  We have to be willing to make tough decisions today and follow through with them.]]></description>
										<content:encoded><![CDATA[<div class="entry">


<p class="wp-block-paragraph">I&#8217;ve struggled to write this week. On the one hand, I want to get on with explaining the <a href="https://thargy.com/2019/09/to-move-on-from-ownership/">motivations behind the creation of a new Institute to promote Stewardship in business</a>.  I&#8217;m particularly excited as things progress and come together.  However, the news is awash with the <a href="https://news.sky.com/story/thomas-cook-collapse-anger-mounts-over-bosses-bonuses-as-brits-brought-back-11818203">collapse of Thomas Cook</a>, a company within the sector I work.</p>



<p class="wp-block-paragraph">When the <a href="http://www.travelweekly.co.uk/articles/339320/malvern-group-goes-into-administration">Malvern Group collapsed</a> in August, taking LateRooms and Superbreak with it, I was upset.  The 250 employees that lost their jobs were people I knew.  Some of them I count as friends.  It felt wrong reducing their story to a morality tale to promote an agenda.  I feel the same about Thomas Cook and its 21,000 employees.  Their pain is genuine and incredibly fresh.  What they need are jobs not platitudes, nor wagon hoppers keen to grab attention.</p>



<p class="wp-block-paragraph">There are a lot of sensationalist articles out there, decrying the executive pay, the role of investors and shareholders.  A sentiment to which I&#8217;m naturally inclined.  However, I need to resist the temptation to pile on.  I wasn&#8217;t in the room, and so I&#8217;m not going to pass judgement on anyone involved.  The story of the collapse is unquestionably far more complex than the headlines.  Their stories will come out in time, and there will be an opportunity for reflection and presumably condemnation.  I hope that individuals will not be allowed to get rich off the pain caused by this failure.  It seems a vain hope, a ship that has probably already sailed.</p>



<p class="wp-block-paragraph">The unavoidable truth is that our world is becoming less fair.  Greed and self-interest are on the rise, and that indulgence has an inescapable cost that is too often paid by the most vulnerable.  We have become obsessed with the acquisition of wealth, rather than the enrichment of character.  Instead, I encourage you to take 5 minutes to <a href="https://www.youtube.com/watch?v=KAJsdgTPJpU&amp;feature=youtu.be">watch the incredible Greta Thunberg</a> remind us of the real cost of chasing <em>&#8220;money and the fairytales of eternal economic growth.&#8221;</em></p>



<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe class="youtube-player" width="480" height="270" src="https://www.youtube.com/embed/KAJsdgTPJpU?version=3&#038;rel=1&#038;showsearch=0&#038;showinfo=1&#038;iv_load_policy=1&#038;fs=1&#038;hl=en-GB&#038;autohide=2&#038;wmode=transparent" allowfullscreen="true" style="border:0;" sandbox="allow-scripts allow-same-origin allow-popups allow-presentation allow-popups-to-escape-sandbox"></iframe>
</div><figcaption>Greta Thunberg reminds us our future is watching</figcaption></figure>



<p class="wp-block-paragraph">At some point, as business leaders, we have to stop looking towards tomorrow to fix the problems of our making.  Procrastination is not the painless solution it promises.  We have to be willing to make tough decisions today and follow through with them.   It is not enough to point at the greed of others and forgive our own with a <a href="https://en.wikipedia.org/wiki/Whataboutism">Trumpesque Whataboutism</a>.</p>



<p class="wp-block-paragraph">As Greta says, so prophetically, if we don&#8217;t change, we won&#8217;t be forgiven.</p>


</div><h3>Related Images:</h3> [<a href="https://thargy.com/2019/09/a-note-on-the-news/">See image gallery at thargy.com</a>] ]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">776</post-id>	</item>
		<item>
		<title>To move on from ownership</title>
		<link>https://thargy.com/2019/09/to-move-on-from-ownership/</link>
					<comments>https://thargy.com/2019/09/to-move-on-from-ownership/#comments</comments>
		
		<dc:creator><![CDATA[thargy]]></dc:creator>
		<pubDate>Fri, 13 Sep 2019 12:59:16 +0000</pubDate>
				<category><![CDATA[Personal]]></category>
		<category><![CDATA[EOT]]></category>
		<category><![CDATA[Ownership]]></category>
		<category><![CDATA[Stewardship]]></category>
		<guid isPermaLink="false">https://thargy.com/?p=771</guid>

					<description><![CDATA[I believe a focus on Stewardship over Ownership is a good thing, and though it's not easy, putting Stewardship at the heart of business is a worthwhile mission.]]></description>
										<content:encoded><![CDATA[<div class="entry">


<p class="wp-block-paragraph">Anyone who has visited me at work has probably had the pleasure of meeting our two favourite volunteers, Bea and Bo. I say &#8220;volunteers&#8221; as we recently converted to a&nbsp;<a target="_blank" href="https://www.livingwage.org.uk/" rel="noreferrer noopener">Living Wage employer</a>, so we no longer consider them part of the staff!</p>



<p class="wp-block-paragraph">In the UK, dogs are legally considered as property, and as such, I legally own&nbsp;<em>my&nbsp;</em>dogs (see the&nbsp;<a target="_blank" href="http://www.legislation.gov.uk/ukpga/1968/60" rel="noreferrer noopener">Theft Act 1968</a>&nbsp;clause 4 (4) in case you&#8217;re wondering).&nbsp;</p>



<div class="wp-block-image"><figure class="alignright is-resized"><img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/thargy.com/wp-content/uploads/2019/09/Bea-and-Bo-at-work.jpg?resize=278%2C159&#038;ssl=1" alt="" class="wp-image-772" width="278" height="159" srcset="https://i0.wp.com/thargy.com/wp-content/uploads/2019/09/Bea-and-Bo-at-work.jpg?resize=480%2C274&amp;ssl=1 480w, https://i0.wp.com/thargy.com/wp-content/uploads/2019/09/Bea-and-Bo-at-work.jpg?resize=300%2C171&amp;ssl=1 300w, https://i0.wp.com/thargy.com/wp-content/uploads/2019/09/Bea-and-Bo-at-work.jpg?resize=768%2C439&amp;ssl=1 768w, https://i0.wp.com/thargy.com/wp-content/uploads/2019/09/Bea-and-Bo-at-work.jpg?w=1920&amp;ssl=1 1920w" sizes="(max-width: 278px) 100vw, 278px" /><figcaption>Bea and Bo at &#8216;work&#8217;</figcaption></figure></div>



<p class="wp-block-paragraph">Ownership is a word that is banded about a lot, it&#8217;s all about&nbsp;<em>rights</em>, and in many cases,&nbsp;<em>exclusive rights</em>. It&#8217;s about what an owner is allowed to do with their property.  It&#8217;s not about what rights that property has.  As a concept,&nbsp;<a target="_blank" href="https://en.wikipedia.org/wiki/Ownership" rel="noreferrer noopener">ownership</a>&nbsp;sits at the very foundation of our&nbsp;<a target="_blank" href="https://en.wikipedia.org/wiki/Capitalism" rel="noreferrer noopener">capitalist</a>&nbsp;society.</p>



<p class="wp-block-paragraph">However, if you&#8217;re a pet owner like me, you hopefully don&#8217;t <em>feel</em> much like an owner, after all owning a pet is a huge responsibility.  Walking dogs, feeding them, taking them to the vet, is an exhausting job &#8211; particularly when they bark at 2AM to let you know they&#8217;re still on watch.  As I write, Bo is making it quite clear that she expects to go play in the garden at work.  You do such things, and many more, because you care about your pets, they matter, you love them.  I&#8217;m their steward.  <a rel="noreferrer noopener" target="_blank" href="https://www.dictionary.com/browse/stewardship">Stewardship</a> is <em>&#8220;the responsible overseeing and protection of something considered worth caring for and preserving&#8221;</em>.</p>



<p class="wp-block-paragraph">As I mentioned in <a rel="noreferrer noopener" target="_blank" href="https://thargy.com/2019/08/opening-doors/">my last post</a>, I recently gained 100% ownership of Web Applications UK.  Legally, it became <em>my </em>company <em>exclusively</em>.  Just like Bea and Bo though, it came with a considerable burden of responsibility (for example, see the <a rel="noreferrer noopener" target="_blank" href="http://www.legislation.gov.uk/ukpga/2006/46/contents">Companies Act 2006</a>).  It&#8217;s a responsibility I carry because I care about it, it matters, I love it.  Sadly though, I see too many cases where companies are just a resource to be exploited.  Not all dog owners are good dog stewards<em>,</em> but, in my experience, far fewer company owners are <em>good </em>stewards.  </p>



<p class="wp-block-paragraph">Social media and the news outlets rightly explode in anger when they see a dog being mistreated. However, when a business owner rips the heart out of his own business, through greed, that&#8217;s expected.  After all, are not companies there to serve their masters, isn&#8217;t that how to get ahead?  Should we care about the impact on the employees, the customers, or the wider community?</p>



<p class="wp-block-paragraph">There&#8217;s an exception to the pervasive nature of ownership &#8211; you can&#8217;t own people.  On 26 July 1833, the&nbsp;<a target="_blank" href="http://www.legislation.gov.uk/ukpga/Will4/3-4/73/contents" rel="noreferrer noopener">Slavery Abolition Act</a>&nbsp;had its third reading in the House of Commons.&nbsp;&nbsp;<a target="_blank" href="https://en.wikipedia.org/wiki/William_Wilberforce" rel="noreferrer noopener">William Wilberforce</a>&nbsp;died 3 days later, having waged a successful 46-year war against slavery, horrified at the&nbsp;<em>&#8220;greed and avarice of the owners&#8221;</em>.  We should never be surprised when focussing on what we can take, on our exclusive rights, leads to such greed.</p>



<p class="wp-block-paragraph">For many pet owners, they consider their pets to be like children.  As can be seen, the law currently sees it differently.  You don&#8217;t <em>own </em>your children.  Like Wilberforce, I think that&#8217;s an excellent thing; and so, just because I <em>legally </em>own Bea and Bo, I don&#8217;t consider myself their owner.  As far as <em>my </em>company goes, it shouldn&#8217;t be surprising I feel precisely the same way.  Web Applications UK is not <em>mine</em>, it&#8217;s ours.  I&#8217;m not really giving it away, it was never mine to give &#8211; regardless of what the law says on the matter.  If you believe, as I do, that a Company is, at its core, a <a rel="noreferrer noopener" target="_blank" href="https://www.dictionary.com/browse/company"><em>group of people</em></a>, it begs an important question.  Why can we <em>own </em>a Company?  After all, has the ownership of Companies really been a net positive for our society?</p>



<p class="wp-block-paragraph"> We can&#8217;t all be Wilberforce &#8211; I certainly can&#8217;t compare my underwhelming achievements to date with his.  I&#8217;m unlikely to abolish pet ownership and the idea that I could eliminate company ownership appears laughable.  People laughed at Wilberforce though, and like him, I am <em>&#8220;too young to realize that certain things are impossible&#8230; So [I] will do them anyway&#8221;</em>.  Children prove that ownership is an unnecessary pre-requisite to success.  Indeed, ownership is more frequently an obstacle.  I believe a focus on Stewardship over Ownership is a good thing, and though it&#8217;s not easy, putting Stewardship at the heart of companies is a worthwhile mission. </p>



<p class="wp-block-paragraph">It&#8217;s evident in the creation of <a rel="noreferrer noopener" target="_blank" href="https://www.gov.uk/employee-ownership">Employee Ownership Trusts</a> that the government is starting to grapple with that same avarice and greed that Wilberforce fought. In fact, the structures I&#8217;m in the process of creating to gift my company to are based firmly on EOTs as a vital step forward. I&#8217;m just not convinced that the solution is <em>more </em>ownership.  That&#8217;s why I&#8217;m fighting to create a new form of EOT called an Employee Stewardship Trust.  Maybe, by changing the emphasis, one day, we can abolish <a rel="noreferrer noopener" target="_blank" href="https://www.businessinsider.com/most-american-workers-are-slaves-2014-4?r=US&amp;IR=T">corporate slavery</a> too.</p>


</div><h3>Related Images:</h3> [<a href="https://thargy.com/2019/09/to-move-on-from-ownership/">See image gallery at thargy.com</a>] ]]></content:encoded>
					
					<wfw:commentRss>https://thargy.com/2019/09/to-move-on-from-ownership/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">771</post-id>	</item>
		<item>
		<title>Opening Doors</title>
		<link>https://thargy.com/2019/08/opening-doors/</link>
					<comments>https://thargy.com/2019/08/opening-doors/#comments</comments>
		
		<dc:creator><![CDATA[thargy]]></dc:creator>
		<pubDate>Fri, 30 Aug 2019 14:10:22 +0000</pubDate>
				<category><![CDATA[Management]]></category>
		<guid isPermaLink="false">http://thargy.com/?p=752</guid>

					<description><![CDATA[On 7 October 2019, I’ll be looking back over 14 years at Web Applications UK, and celebrating my last day as Chief Executive. When I joined the company all those years ago, it was as a Consultant, working just four days a week. Within 18 months, I was asked to take over as Managing Director ...]]></description>
										<content:encoded><![CDATA[<div class="entry">


<p class="wp-block-paragraph">On 7
October 2019, I’ll be looking back over 14 years at Web Applications UK,
and celebrating my last day as Chief Executive.</p>



<p class="wp-block-paragraph">When I joined the company all those years ago, it was as
a Consultant, working just four days a week. Within 18 months, I was asked to
take over as Managing Director and became Chief Executive in February 2009. The
ensuing decade has been a trial by fire and a great big mirror in which to
discover who I am. An experience for which I am profoundly grateful.</p>



<p class="wp-block-paragraph">From the outset, my goal has been to innovate &#8211; to try
something new. The relentless pursuit of profit has never driven me; instead, I
have sought to have a positive impact on the lives of those around me. I&#8217;ve
certainly not always succeeded, but I&#8217;ve learnt and grown and made some
wonderful friends along the way. When we work for each other, instead of for
ourselves, we all benefit. As I said&nbsp;<a href="http://thargy.com/2012/05/pressing-the-reset-button-on-business/" target="_blank" rel="noreferrer noopener">back in 2012</a>,&nbsp;<em>&#8220;If
one can accept people can rise above selfishness, surely it is a small step to
believe that business can too. And if we admire animals for morality, and we
clearly admire people for the same traits, then why do we not judge businesses
– the ultimate endeavour of our collective efforts – in exactly the same way.
Surely the last measure of a business should be its level of self-interest?&#8221;</em></p>



<p class="wp-block-paragraph">The truth is, self-interest already dominates too much of
business, and it is profoundly damaging &#8211; something I have frequently
experienced first hand. I don&#8217;t accept it has to be that way though, and I
believe I can&#8217;t be the only one who feels that way. Indeed, the&nbsp;<a href="http://thargy.com/2011/10/the-measure-of-success/" target="_blank" rel="noreferrer noopener">focus on people over profit</a>&nbsp;has allowed Web Applications UK to be profoundly
successful over the last 20 years. On taking the reins in 2007, one of my first
acts was to attempt the formation of an Employee Benefit Trust, which led to
the creation of our profit share scheme. I have always wanted to go much
further though, and earlier this year, I gained 100% control of Web
Applications UK and its assets. It&#8217;s at such times in life that we face the
hard choice of staying true to our convictions or taking the easy path. I now
have the opportunity to follow my dream of creating a new kind of business.
That opportunity comes with the temptation of holding on to all I&#8217;ve fought so
hard to create.</p>



<p class="wp-block-paragraph">It should come as no surprise that my wife and I have
decided to take this fantastic company and place it into the hands of an
Employee Ownership Trust. We&#8217;re doing it a little differently though.</p>



<p class="wp-block-paragraph">For a start, we&#8217;re not selling the company; it&#8217;s a gift.
Secondly, we prefer to call it a Stewardship Trust. The Trust&#8217;s members (the
Employees) may&nbsp;<em>legally own&nbsp;</em>the assets, but it&#8217;s in the same way that we&nbsp;<em>legally own</em>&nbsp;our
beloved dogs, Bea and Bo. Stewardship is a beautiful responsibility of care,
where we invest into something other than ourselves for the joy of it – where
the reward is the effect, not the goal. The Trust will be made up of Stewards.
</p>



<p class="wp-block-paragraph">What we are giving away is worth significantly more than we&#8217;ve earned over the last fourteen years. We still live in Chadderton, in a modest home, with a mortgage. We are not wealthy, but we are grateful to have the opportunity to do something truly unique and original. Building something that outlasts us makes us far richer than holding tightly to the control we now have. When you love something as much as we love this company and its people, you only want the best for it, and them. Eventually, you have to let things go – to fly on their own.</p>



<p class="wp-block-paragraph">Over the next few months, our focus will be on the
creation of the Trust, and the preparations necessary to affect the transfer of
the company and properties into it. We will continue to advocate for the
movement and be there to support and encourage the directors and staff. We
remain committed to working for the success of the Trust and its members. We
hope to see more businesses join us in time as we demonstrate the benefits of
allowing people to work for each other – rather than to enrich a chosen few.

It&#8217;s
an end of an era, but the start of something new and exciting. One of my last
acts as Chief Executive will be to consign the old name for the company to
history. The signs are already coming down, the branding being cleared away to
make way for something new. Web Applications UK will be stepping down with me.
What rises in its place will be something far better. It&#8217;s a grand experiment,
a beautiful risk, a new way of doing business. After all, that&#8217;s what life
should be about right?



</p>


</div><h3>Related Images:</h3>]]></content:encoded>
					
					<wfw:commentRss>https://thargy.com/2019/08/opening-doors/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">752</post-id>	</item>
		<item>
		<title>Understanding digital infrastructure in a digital age</title>
		<link>https://thargy.com/2014/08/understanding-digital-infrastructure-in-a-digital-age/</link>
		
		<dc:creator><![CDATA[thargy]]></dc:creator>
		<pubDate>Fri, 01 Aug 2014 10:17:09 +0000</pubDate>
				<category><![CDATA[Chamber of Commerce]]></category>
		<category><![CDATA[Personal]]></category>
		<guid isPermaLink="false">http://thargy.com/?p=485</guid>

					<description><![CDATA[If you ask the average business owner whether they have internet access, they are very likely to answer ‘yes’.&#160; If you ask them if they have broadband, most, but not all will continue to answer confidentially in the affirmative.&#160; If you ask them if they have ‘superfast broadband’ a look of confusion slowly spreads across ...]]></description>
										<content:encoded><![CDATA[<div class="entry">
<p>If you ask the average business owner whether they have internet access, they are very likely to answer ‘yes’.&nbsp; If you ask them if they have <a title="Broadband" href="https://en.wikipedia.org/wiki/Broadband" target="_blank" rel="noopener noreferrer">broadband</a>, most, but not all will continue to answer confidentially in the affirmative.&nbsp; If you ask them if they have ‘<a title="What exactly is superfast broadband?" href="https://www.enta.net/opinion/2010/11/09/what-exactly-is-superfast-broadband/" target="_blank" rel="noopener noreferrer">superfast broadband</a>’ a look of confusion slowly spreads across their face.&nbsp; This isn’t that surprising, as the term is little more than a marketing peg used to upsell consumers, but it is a term readily adopted by <a title="OfCom homepage" href="https://www.ofcom.org.uk/" target="_blank" rel="noopener noreferrer">OfCom</a> and Whitehall.</p>
<p>OfCom define ‘superfast’ as 25Mb/s or greater, which at first glance seems a helpful clarification.&nbsp; This definition is based, in part, on the fact that the maximum speed of an ADSL2+ line is 24Mbit/s.&nbsp; When OfCom talk of ‘superfast’ they really mean the signal is being carried by a fibre optical cable, at least until the cabinet, so the distance travelled over copper wires is minimised.</p>
<p>Unfortunately, <a title="Data rate units" href="https://en.wikipedia.org/wiki/Data_rate_units" target="_blank" rel="noopener noreferrer">megabits per second</a> is not a great way to measure connection value. &nbsp;It’s equivalent to measuring a car’s performance based on its top speed in feet per second.&nbsp; Firstly the average consumer is already educated to think of bytes not bits when purchasing IT equipment such as RAM and hard drives, a bit is 1/8<sup>th</sup> of a byte, so 8Mb/s is actually only 1 MB/s (megabyte per second). &nbsp;More importantly, a savvy car purchaser will look at acceleration, fuel economy, and a host of other features when purchasing a car, top speed is actually not that important (so long as it’s over 70mph), and every car buyer knows that it’s not just the make and model that matter, it’s the actual performance of the specific car you’re buying.&nbsp; Just like cars, identical packages can have very different performance for the end user, based on a number of factors, especially distance to the cabinet, and contention.&nbsp; <a title="Contention" href="https://en.wikipedia.org/wiki/Contention_ratio" target="_blank" rel="noopener noreferrer">Contention</a>, or how many people are trying to use the same connection at the same time, is the least well understood, and yet clearly vital factor when assessing the true value of your internet connection.&nbsp; In our car analogy contention is the difference between wide open roads and congested country lanes.</p>
<p>When connecting to the internet there are actually two ‘top speeds’, <a title="Download definition" href="https://en.wikipedia.org/wiki/Download" target="_blank" rel="noopener noreferrer">download</a> and <a title="Upload definition" href="https://en.wikipedia.org/wiki/Upload" target="_blank" rel="noopener noreferrer">upload</a> speed – and they are rarely the same.&nbsp; When <a title="Internet Service Provider" href="https://en.wikipedia.org/wiki/ISP" target="_blank" rel="noopener noreferrer">ISP</a>s publish their ‘speeds’ they often refer to the maximum theoretical download speed, which isn’t surprising as these are frequently 10-20% higher than the actual average speed over 24hrs (and worse at peak contention times, around 8-10PM) and are normally at least four times faster than the average upload speed.&nbsp; In August 2013 the average download speed for the UK was 14.7Mbit/s compared to 1.8Mbit/s upload (over 8 times slower uploads).</p>
<p>For consumers, the asymmetry between download and upload speeds isn’t actually that big a problem, in fact it’s a deliberate design decision.&nbsp; Consumers largely download from the internet, they send very little back, in comparison.&nbsp; The problem is that many businesses are ‘producers’ not consumers, for them the upload speed is absolutely critical, but our networks are not designed to meet this need, forcing many businesses to purchase extremely expensive leased lines to get the upload speeds necessary.&nbsp; Our small businesses are very much second class citizens in the digital age.</p>
<p>A trawl through statements made by our policy makers demonstrates a complete lack of understanding about the subtleties around internet connectivity.&nbsp; It seems impossible to have vital discussions about improving our digital infrastructure when few understand the difference between 2Mb and 200Mbit, never mind the importance of upload speeds to companies trading over the internet.&nbsp; This leads to an overly cosy relationship between regulators and the ISP industry and needs to be addressed urgently.&nbsp; There are huge factors affecting our future ability to compete in the digital age, from <a title="Net neutrality" href="https://en.wikipedia.org/wiki/Net_neutrality" target="_blank" rel="noopener noreferrer">net neutrality</a>, to the importance of <a title="Fiber to the premises." href="https://en.wikipedia.org/wiki/Fiber_to_the_premises#Fiber_to_the_premises" target="_blank" rel="noopener noreferrer">fibre to the premise</a> verses <a title="Fiber to the cabinet" href="https://en.wikipedia.org/wiki/Fiber_to_the_cabinet#Fiber_to_the_curb.2Fcabinet" target="_blank" rel="noopener noreferrer">fibre to the cabinet</a>.</p>
<p>Until our policy makers understand the details, it’s hard to see how they can influence the outcomes positively.</p>
</div>
<h3>Related Images:</h3>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">485</post-id>	</item>
		<item>
		<title>Controlling access to shared resources in an asynchronous world</title>
		<link>https://thargy.com/2014/03/controlling-access-to-shared-resources-in-an-asynchronous-world/</link>
		
		<dc:creator><![CDATA[thargy]]></dc:creator>
		<pubDate>Fri, 28 Mar 2014 05:54:52 +0000</pubDate>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Asynchronous Programming]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[AsyncDebouncedFunction]]></category>
		<category><![CDATA[AsyncLock]]></category>
		<category><![CDATA[AsyncReaderWriterLock]]></category>
		<category><![CDATA[AsyncSemaphore]]></category>
		<category><![CDATA[ConcurrentExclusiveSchedulerPair]]></category>
		<category><![CDATA[ConcurrentScheduler]]></category>
		<category><![CDATA[ExclusiveScheduler]]></category>
		<guid isPermaLink="false">http://thargy.com/?p=475</guid>

					<description><![CDATA[In my last post I introduced the AsyncLock and AsyncDebouncedFunction.  AsyncLock is a fantastic way of asynchronously holding a &#8216;lock&#8217; without actually blocking threads.  It is the natural go to class for resource synchronization, but there are alternatives (with caveats). In .Net 4.5 the ConcurrentExclusiveSchedulerPair was introduced, offering a powerful approach to concurrency control.  Using this ...]]></description>
										<content:encoded><![CDATA[<div class="entry">
<p>In my <a title="Debouncing asynchronous operations" href="http://thargy.com/2014/03/debouncing-asynchronous-operations/">last post</a> I introduced the <a title="Building Async Coordination Primitives, Part 6: AsyncLock" href="https://blogs.msdn.microsoft.com/pfxteam/2012/02/12/building-async-coordination-primitives-part-6-asynclock/" target="_blank" rel="noopener noreferrer">AsyncLock</a> and <a title="Debouncing asynchronous operations" href="http://thargy.com/2014/03/debouncing-asynchronous-operations/" target="_blank" rel="noopener noreferrer">AsyncDebouncedFunction</a>.  <a title="Building Async Coordination Primitives, Part 6: AsyncLock" href="https://blogs.msdn.microsoft.com/pfxteam/2012/02/12/building-async-coordination-primitives-part-6-asynclock/" target="_blank" rel="noopener noreferrer">AsyncLock</a> is a fantastic way of asynchronously holding a &#8216;lock&#8217; without actually blocking threads.  It is the natural go to class for resource synchronization, but there are alternatives (with caveats).</p>
<p>In .Net 4.5 the <a title="ConcurrentExclusiveSchedulerPair Class" href="https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.concurrentexclusiveschedulerpair?redirectedfrom=MSDN&amp;view=netframework-4.8" target="_blank" rel="noopener noreferrer">ConcurrentExclusiveSchedulerPair</a> was introduced, offering a powerful approach to concurrency control.  Using this class, we can schedule tasks to run concurrently or exclusively, and at first glance it appears to offer a powerful alternative to my <a title="Debouncing asynchronous operations" href="http://thargy.com/2014/03/debouncing-asynchronous-operations/" target="_blank" rel="noopener noreferrer">AsyncDebouncedFunction</a>.</p>
<p>Consider the following code:</p>
<pre class="lang:c# decode:true" title="Test ConcurrentExclusiveSchedulerPair">int a = 0;
Stopwatch s = new Stopwatch();
// Create a task factory that schedules tasks to run exclusively.
TaskFactory exclusiveFactory = new TaskFactory(new ConcurrentExclusiveSchedulerPair().ExclusiveScheduler);
Func&lt;cancellationtoken, task&lt;int=""&gt;&gt; runner = token =&gt; exclusiveFactory.StartNew(
	() =&gt; {
		int run = Interlocked.Increment(ref a);
		Console.WriteLine("{0}: Started {1}", s.Elapsed, run);
		Thread.Sleep(1000);

		Console.WriteLine("{0}: Completed {1}", s.Elapsed, run);
		return run;
	}, token);
Console.WriteLine();
Console.WriteLine("Testing ConcurrentExclusiveSchedulerPair");
a=0;
s.Restart();
try {
	await Task.WhenAll(
		runner(new CancellationTokenSource(TimeSpan.FromSeconds(0.5)).Token)
			.ContinueWith(i =&gt; Console.WriteLine("{0}: Result {1}", s.Elapsed, i.Result), TaskContinuationOptions.OnlyOnRanToCompletion),
		runner(CancellationToken.None)
			.ContinueWith(i =&gt; Console.WriteLine("{0}: Result {1}", s.Elapsed, i.Result), TaskContinuationOptions.OnlyOnRanToCompletion),
		runner(CancellationToken.None)
			.ContinueWith(i =&gt; Console.WriteLine("{0}: Result {1}", s.Elapsed, i.Result), TaskContinuationOptions.OnlyOnRanToCompletion));
} catch (TaskCanceledException e) {
	Console.WriteLine(e.Message);
}</pre>
<p>This creates a new TaskFactory which makes use of the <a title="ConcurrentExclusiveSchedulerPair Class" href="https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.concurrentexclusiveschedulerpair?redirectedfrom=MSDN&amp;view=netframework-4.8" target="_blank" rel="noopener noreferrer">ConcurrentExclusiveSchedulerPair</a>&#8216;s <a title="ConcurrentExclusiveSchedulerPair.ExclusiveScheduler Property" href="https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.concurrentexclusiveschedulerpair.exclusivescheduler?redirectedfrom=MSDN&amp;view=netframework-4.8" target="_blank" rel="noopener noreferrer">ExclusiveScheduler</a>.  Any tasks created on this factory will run sequentially rather than concurrently, which looks like a great start.  In fact, running this code we get the following result:</p>
<pre>Testing ConcurrentExclusiveSchedulerPair
00:00:00.0012267: Started 1
00:00:01.0013490: Completed 1
00:00:01.0014078: Started 2
00:00:01.0017885: Result 1
00:00:02.0019925: Completed 2
00:00:02.0021238: Started 3
00:00:02.0024653: Result 2
00:00:03.0022518: Completed 3
00:00:03.0026929: Result 3</pre>
<p>Showing each task runs one after the other, as we expect.  The first problem is that this doesn&#8217;t take into account when we created each task, so we don&#8217;t get the result re-use we had with <a title="Debouncing asynchronous operations" href="http://thargy.com/2014/03/debouncing-asynchronous-operations/" target="_blank" rel="noopener noreferrer">AsyncDebouncedFunction</a>.  For that we&#8217;d have to create a slightly more involved class, that only runs the inner function on the <a title="ConcurrentExclusiveSchedulerPair.ExclusiveScheduler Property" href="https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.concurrentexclusiveschedulerpair.exclusivescheduler?redirectedfrom=MSDN&amp;view=netframework-4.8" target="_blank" rel="noopener noreferrer">ExclusiveScheduler</a>.  Before we jump into such an implementation though, consider what happens if we run asynchronous code on the scheduler that yields, for example:</p>
<pre class="striped:false lang:c# mark:5-13 decode:true">int a = 0;
Stopwatch s = new Stopwatch();
// Create a task factory that schedules tasks to run exclusively.
TaskFactory exclusiveFactory = new TaskFactory(new ConcurrentExclusiveSchedulerPair().ExclusiveScheduler);
Func&lt;cancellationtoken, task&lt;int=""&gt;&gt; runner = token =&gt; exclusiveFactory.StartNew(
	async () =&gt; {
		int run = Interlocked.Increment(ref a);
		Console.WriteLine("{0}: Started {1}", s.Elapsed, run);
		await Task.Delay(1000, token);

		Console.WriteLine("{0}: Completed {1}", s.Elapsed, run);
		return run;
	}, token).Unwrap();
Console.WriteLine();
Console.WriteLine("Testing ConcurrentExclusiveSchedulerPair");
a=0;
s.Restart();
try {
	await Task.WhenAll(
		runner(new CancellationTokenSource(TimeSpan.FromSeconds(0.5)).Token)
			.ContinueWith(i =&gt; Console.WriteLine("{0}: Result {1}", s.Elapsed, i.Result), TaskContinuationOptions.OnlyOnRanToCompletion),
		runner(CancellationToken.None)
			.ContinueWith(i =&gt; Console.WriteLine("{0}: Result {1}", s.Elapsed, i.Result), TaskContinuationOptions.OnlyOnRanToCompletion),
		runner(CancellationToken.None)
			.ContinueWith(i =&gt; Console.WriteLine("{0}: Result {1}", s.Elapsed, i.Result), TaskContinuationOptions.OnlyOnRanToCompletion));
} catch (TaskCanceledException e) {
	Console.WriteLine(e.Message);
}</pre>
<p>Here, we&#8217;ve told the </p>
<pre class="lang:c# decode:1 inline:1 " >runner</pre>
<p>  to run asynchronous code that uses <a title="Task.Delay Method (TimeSpan)" href="https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.delay?redirectedfrom=MSDN&amp;view=netframework-4.8" target="_blank" rel="noopener noreferrer">Task.Delay()</a> instead of <a title="Thread.Sleep Method (Int32)" href="https://docs.microsoft.com/en-us/dotnet/api/system.threading.thread.sleep?redirectedfrom=MSDN&amp;view=netframework-4.8" target="_blank" rel="noopener noreferrer">Thread.Sleep()</a>.  Note the <a title="TaskExtensions.Unwrap Method (Task&lt;Task&gt;)" href="https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.taskextensions.unwrap?redirectedfrom=MSDN&amp;view=netframework-4.8" target="_blank" rel="noopener noreferrer">Unwrap()</a> call as we&#8217;re running an asynchronous operation asynchronously!  The result of running this code is not what you might hope (unless you&#8217;re paying attention):</p>
<pre>Testing ConcurrentExclusiveSchedulerPair
00:00:00.0017058: Started 1
00:00:00.0022739: Started 2
00:00:00.0022872: Started 3
00:00:01.0161957: Completed 3
00:00:01.0162235: Completed 2
00:00:01.0165797: Result 2
00:00:01.0166038: Result 3
A task was canceled.</pre>
<p>At first glance there doesn&#8217;t appear to be any concurrency at all!  In fact, that&#8217;s not entirely true at all, the <a title="ConcurrentExclusiveSchedulerPair.ExclusiveScheduler Property" href="https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.concurrentexclusiveschedulerpair.exclusivescheduler?redirectedfrom=MSDN&amp;view=netframework-4.8" target="_blank" rel="noopener noreferrer">ExclusiveScheduler</a> is in fact exclusively scheduling the tasks, however <a title="Task.Delay Method (TimeSpan)" href="https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.delay?redirectedfrom=MSDN&amp;view=netframework-4.8" target="_blank" rel="noopener noreferrer">Task.Delay()</a> is non-blocking and so yields execution back to the scheduler which allows a waiting task to execute, we can best illustrate this by tweaking our function slightly:</p>
<pre class="lang:c# decode:true" title="Demonstrating the difference between Thread.Sleep and Task.Delay">async () =&gt; {
		int run = Interlocked.Increment(ref a);
		Console.WriteLine("{0}: Started {1}", s.Elapsed, run);
		Thread.Sleep(100);
		Console.WriteLine("{0}: Yielding {1}", s.Elapsed, run);
		await Task.Delay(800, token);

		Console.WriteLine("{0}: Restarting {1}", s.Elapsed, run);
		Thread.Sleep(100);
		Console.WriteLine("{0}: Completed {1}", s.Elapsed, run);
		return run;
	}</pre>
<p>Our function now blocks for 100ms on either side of the 800ms delay, which should illustrate the exclusivity nicely:</p>
<pre>Testing ConcurrentExclusiveSchedulerPair
00:00:00.0015790: Started 1
00:00:00.1020952: Yielding 1
00:00:00.1029492: Started 2
00:00:00.2035512: Yielding 2
00:00:00.2036396: Started 3
00:00:00.3043756: Yielding 3
00:00:01.0145095: Restarting 2
00:00:01.1156219: Completed 2
00:00:01.1156772: Restarting 3
00:00:01.1160992: Result 2
00:00:01.2159296: Completed 3
00:00:01.2163921: Result 3
A task was canceled.</pre>
<p>Now we can see that each task doesn&#8217;t start until the preceding task yields control to the scheduler, so we do still have exclusivity, and the tasks are not running at the same time as each other.  However, they are free to interleave each other.  The take home from these examples is that the <a title="ConcurrentExclusiveSchedulerPair Class" href="https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.concurrentexclusiveschedulerpair?redirectedfrom=MSDN&amp;view=netframework-4.8" target="_blank" rel="noopener noreferrer">ConcurrentExclusiveSchedulerPair</a>&#8216;s <a title="ConcurrentExclusiveSchedulerPair.ExclusiveScheduler Property" href="https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.concurrentexclusiveschedulerpair.exclusivescheduler?redirectedfrom=MSDN&amp;view=netframework-4.8" target="_blank" rel="noopener noreferrer">ExclusiveScheduler</a> can prevent concurrent access to a shared resource, but the resource may be accessed by another thread at any point you yield control.  When you need to hold a resource across yields then <a title="Building Async Coordination Primitives, Part 6: AsyncLock" href="https://blogs.msdn.microsoft.com/pfxteam/2012/02/12/building-async-coordination-primitives-part-6-asynclock/" target="_blank" rel="noopener noreferrer">AsyncLock</a> is a more appropriate choice.</p>
<p>The other advantage of <a title="ConcurrentExclusiveSchedulerPair Class" href="https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.concurrentexclusiveschedulerpair?redirectedfrom=MSDN&amp;view=netframework-4.8" target="_blank" rel="noopener noreferrer">ConcurrentExclusiveSchedulerPair</a> is that is also has a <a title="ConcurrentExclusiveSchedulerPair.ConcurrentScheduler Property" href="https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.concurrentexclusiveschedulerpair.concurrentscheduler?redirectedfrom=MSDN&amp;view=netframework-4.8" target="_blank" rel="noopener noreferrer">ConcurrentScheduler </a>that allows concurrent scheduling (with a configurable concurrency limit, like <a title="Building Async Coordination Primitives, Part 5: AsyncSemaphore" href="https://devblogs.microsoft.com/pfxteam/building-async-coordination-primitives-part-5-asyncsemaphore/" target="_blank" rel="noopener noreferrer">AsyncSemaphore</a>), that won&#8217;t overlap with tasks run on the <a title="ConcurrentExclusiveSchedulerPair.ExclusiveScheduler Property" href="https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.concurrentexclusiveschedulerpair.exclusivescheduler?redirectedfrom=MSDN&amp;view=netframework-4.8" target="_blank" rel="noopener noreferrer">ExclusiveScheduler</a>, in this way you can easily simulate a reader/writer lock, with the same caveats as above.  Of course, <a title="Stephen Toub" href="https://social.msdn.microsoft.com:443/profile/stephen%20toub%20-%20msft/" target="_blank" rel="noopener noreferrer">Stephen Toub</a> also provides an <a title="Building Async Coordination Primitives, Part 7: AsyncReaderWriterLock" href="https://devblogs.microsoft.com/pfxteam/building-async-coordination-primitives-part-7-asyncreaderwriterlock/" target="_blank" rel="noopener noreferrer">AsyncReaderWriterLock</a> for holding locks across yields.</p>
</div>
<h3>Related Images:</h3>
<p> [<a href="https://thargy.com/2014/03/controlling-access-to-shared-resources-in-an-asynchronous-world/">See image gallery at thargy.com</a>] </p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">475</post-id>	</item>
		<item>
		<title>Debouncing asynchronous operations</title>
		<link>https://thargy.com/2014/03/debouncing-asynchronous-operations/</link>
					<comments>https://thargy.com/2014/03/debouncing-asynchronous-operations/#comments</comments>
		
		<dc:creator><![CDATA[thargy]]></dc:creator>
		<pubDate>Thu, 27 Mar 2014 21:47:03 +0000</pubDate>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Asynchronous Programming]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[APM]]></category>
		<category><![CDATA[async]]></category>
		<category><![CDATA[AsyncDebouncedFunction]]></category>
		<category><![CDATA[AsyncLock]]></category>
		<category><![CDATA[AsyncSemaphore]]></category>
		<category><![CDATA[await]]></category>
		<category><![CDATA[Debounce]]></category>
		<category><![CDATA[TPL]]></category>
		<guid isPermaLink="false">http://thargy.com/?p=467</guid>

					<description><![CDATA[With the introduction of the async and await keywords, asynchronous programming has finally become achievable by any .Net developer.  Building on the TPL, async and await extend the C# language specification to make task based programming relatively straight forward, and is a huge step forward from APM. However, being able to write code that runs ...]]></description>
										<content:encoded><![CDATA[<div class="entry">
<p>With the introduction of the <a title="Asynchronous Programming with Async and Awai" href="https://docs.microsoft.com/en-us/previous-versions/hh191443(v=vs.140)?redirectedfrom=MSDN" target="_blank" rel="noopener noreferrer">async and await</a> keywords, asynchronous programming has finally become achievable by any .Net developer.  Building on the <a title="Task Parallel Library (TPL)" href="https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/task-parallel-library-tpl?redirectedfrom=MSDN" target="_blank" rel="noopener noreferrer">TPL</a>, async and await extend the C# language specification to make task based programming relatively straight forward, and is a huge step forward from <a title="Asynchronous Programming Model (APM)" href="https://docs.microsoft.com/en-us/dotnet/standard/asynchronous-programming-patterns/asynchronous-programming-model-apm?redirectedfrom=MSDN" target="_blank" rel="noopener noreferrer">APM</a>.</p>
<p>However, being able to write code that runs asynchronously is only the first step, thinking asynchronously is a whole new set of skills that developers have to master.  For example, how should you access a shared resource from asynchronous code?</p>
<p>There are some great resources out there and one of my favourite blogs is produced by Microsoft&#8217;s <a title="Stephen Toub" href="https://social.msdn.microsoft.com:443/profile/stephen%20toub%20-%20msft/" target="_blank" rel="noopener noreferrer">Stephen Toub</a> who works with the <a title="Parallel Programming with .NET" href="https://blogs.msdn.microsoft.com/pfxteam/" target="_blank" rel="noopener noreferrer">PFXTeam</a>.  A while ago I came across a real gem in this blog, the <a title="Building Async Coordination Primitives, Part 5: AsyncSemaphore" href="https://devblogs.microsoft.com/pfxteam/building-async-coordination-primitives-part-5-asyncsemaphore/" target="_blank" rel="noopener noreferrer">AsyncSemaphore</a>, which allows us to create an <a title="Building Async Coordination Primitives, Part 6: AsyncLock" href="https://blogs.msdn.microsoft.com/pfxteam/2012/02/12/building-async-coordination-primitives-part-6-asynclock/" target="_blank" rel="noopener noreferrer">AsyncLock</a>; which, in turn, helps you answer the question above.</p>
<p>But what else can we use an <a title="Building Async Coordination Primitives, Part 6: AsyncLock" href="https://blogs.msdn.microsoft.com/pfxteam/2012/02/12/building-async-coordination-primitives-part-6-asynclock/" target="_blank" rel="noopener noreferrer">AsyncLock</a> for?  Lots of stuff!</p>
<p>One particularly useful use is to debounce an asynchronous function.  Imagine we have a long running asynchronous function that goes and gets the latest stock price from a web service, if we allow multiple threads to execute the method then it would result in many calls to the same web service, all of which would return the same answer.  A better approach is to run the method once and allow anyone else that asks for the result to wait for the first execution to complete, and return the same result.</p>
<p>Using <a title="Building Async Coordination Primitives, Part 6: AsyncLock" href="https://blogs.msdn.microsoft.com/pfxteam/2012/02/12/building-async-coordination-primitives-part-6-asynclock/" target="_blank" rel="noopener noreferrer">AsyncLock</a> we can create a class for that:</p>
<pre class="lang:c# decode:true" title="AsyncDebouncedFunction">#region © Copyright Web Applications (UK) Ltd, 2013.  All rights reserved.
// Copyright (c) 2013, Web Applications UK Ltd
// All rights reserved.
// 
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of Web Applications UK Ltd nor the
//       names of its contributors may be used to endorse or promote products
//       derived from this software without specific prior written permission.
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL WEB APPLICATIONS UK LTD BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion

using System;
using System.Diagnostics.Contracts;
using System.Threading;
using System.Threading.Tasks;
using JetBrains.Annotations;

namespace WebApplications.Utilities.Threading
{
    /// 
    /// Debounces an asynchronous function.
    /// 
    public class AsyncDebouncedFunction
    {
        /// 
        /// The semaphore controls concurrent access to function execution.
        /// 
        private readonly AsyncLock _lock = new AsyncLock();

        /// 
        /// The asynchronous function to run.
        /// 
        private readonly Func&lt;cancellationtoken, task&lt;tresult=""&gt;&gt; _function;

        /// 
        /// The duration ticks is the number of ticks to leave after a successfully completed function invocation, from the start of the last successful invocation.
        /// 
        private readonly long _durationTicks;

        /// 
        /// The gap ticks is the number of ticks to leave after a successfully completed function invocation, from the end of the last successful invocation.
        /// 
        private readonly long _minimumGapTicks;

        /// 
        /// The next run is the earliest tick that the function can be run again.
        /// 
        private long _nextRun;

        /// 
        /// The last result.
        /// 
        private TResult _lastResult;

        /// 
        /// Initializes a new instance of the  class.
        /// 
        ///The function.
        ///The duration is the amount of time the result of a successful execution is held, after the point a successful request was made.
        ///The minimum gap, is the time left after a successful execution before the function can be run again.
        public AsyncDebouncedFunction(
            Func function,
            TimeSpan duration = default(TimeSpan),
            TimeSpan minimumGap = default(TimeSpan))
            : this(token =&gt; function(), duration, minimumGap)
        {
            Contract.Requires(function != null);
            Contract.Requires(duration &gt;= TimeSpan.Zero);
            Contract.Requires(minimumGap &gt;= TimeSpan.Zero);
        }

        /// 
        /// Initializes a new instance of the  class.
        /// 
        ///The function.
        ///The duration is the amount of time the result of a successful execution is held, after the point a successful request was made.
        ///The minimum gap, is the time left after a successful execution before the function can be run again.
        public AsyncDebouncedFunction(
            Func&lt;cancellationtoken, task&lt;tresult=""&gt;&gt; function,
            TimeSpan duration = default(TimeSpan),
            TimeSpan minimumGap = default(TimeSpan))
        {
            Contract.Requires(function != null);
            Contract.Requires(duration &gt;= TimeSpan.Zero);
            Contract.Requires(minimumGap &gt;= TimeSpan.Zero);

            // Calculate the gap ticks, based on stopwatch frequency.
            _durationTicks = duration.Ticks;
            _minimumGapTicks = minimumGap.Ticks;
            _function = function;
        }

        /// 
        /// Runs the function asynchronously.
        /// 
        ///The token.
        /// An awaitable task, that completes with the debounced result.
        /// If the function is currently running, this will wait until it completes (or
        ///  has been cancelled),
        /// but won't run the function again.  However, if the original function is cancelled, or errors,
        /// then it will run the function again immediately.
        /// 
        public async Task Run(CancellationToken token = default (CancellationToken))
        {
            // Record when the request was made.
            long requested = DateTime.UtcNow.Ticks;

            // Wait until the semaphore says we can go.
            using (await _lock.LockAsync(token))
            {
                // If we're cancelled, or we were requested before the next run date we're done.
                token.ThrowIfCancellationRequested();

                if (requested &lt;= _nextRun)
                    return _lastResult;

                // Await on a task.
                TResult lastResult = await _function(token);

                // If we're cancelled we don't update our next run as we were unsuccessful.
                token.ThrowIfCancellationRequested();

                // Set the next time you can run the function.
                _lastResult = lastResult;
                _nextRun = Math.Max(requested + _durationTicks, DateTime.UtcNow.Ticks + _minimumGapTicks);
                return lastResult;
            }
        }
    }
}</pre>
<p>This allows you to create an asynchronous function that will only have one instance running at any time, any multiple calls to the same function will all wait for the result of the currently executing function.  You can also use the </p>
<pre class="lang:c# decode:1 inline:1 " >minimumGap</pre>
<p> and </p>
<pre class="lang:c# decode:1 inline:1 " >duration</pre>
<p> parameters to cache the result of a successful execution for a period, this is great when you know that an expensive operation&#8217;s result doesn&#8217;t change too frequently, or that it&#8217;s not necessary to have real time, &#8216;fresh&#8217; results (e.g. when serving a web page).</p>
<p>For example, the code below:</p>
<pre class="lang:c# decode:true" title="AsyncDebouncedFunction Test Code">int a = 0;
Stopwatch s = Stopwatch.StartNew();
AsyncDebouncedFunction adf = new AsyncDebouncedFunction(
	async token =&gt; {
		int run = Interlocked.Increment(ref a);
		Console.WriteLine("{0}: Started {1}", s.Elapsed, run);
		await Task.Delay(1000, token);

		Console.WriteLine("{0}: Completed {1}", s.Elapsed, run);
		return run;
	});

try {
	await Task.WhenAll(
		adf.Run(new CancellationTokenSource(TimeSpan.FromSeconds(0.5)).Token)
			.ContinueWith(i =&gt; Console.WriteLine("{0}: Result {1}", s.Elapsed, i.Result), TaskContinuationOptions.OnlyOnRanToCompletion),
		adf.Run()
			.ContinueWith(i =&gt; Console.WriteLine("{0}: Result {1}", s.Elapsed, i.Result), TaskContinuationOptions.OnlyOnRanToCompletion),
		adf.Run()
			.ContinueWith(i =&gt; Console.WriteLine("{0}: Result {1}", s.Elapsed, i.Result), TaskContinuationOptions.OnlyOnRanToCompletion));
} catch (TaskCanceledException e) {
	Console.WriteLine(e.Message);
}</pre>
<p>Produces the following output:</p>
<pre>00:00:00.0007214: Started 1
00:00:00.5006508: Started 2
00:00:01.5147577: Completed 2
00:00:01.5151857: Result 2
00:00:01.5152295: Result 2
A task was canceled.</pre>
<p>The code tries to run the function three times at once.  The first execution is set to timeout after 0.5s, whereas the second and third executions don&#8217;t have a timeout.  The function itself is set to take 1s, therefore the first task will be cancelled before it get&#8217;s the opportunity to complete (after 0.5s), which is OK, because the 2nd task will now start immediately, as the first task failed and there is no result yet.  The second task runs to completion, which means the third task (which was also waiting can make use of the result without running the function again.</p>
<p>Debouncing operations can have a huge impact on the performance of real world systems, so I hope you find this piece of code as useful as I do!</p>
<p>&nbsp;</p>
</div>
<h3>Related Images:</h3>
<p> [<a href="https://thargy.com/2014/03/debouncing-asynchronous-operations/">See image gallery at thargy.com</a>] </p>
]]></content:encoded>
					
					<wfw:commentRss>https://thargy.com/2014/03/debouncing-asynchronous-operations/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">467</post-id>	</item>
		<item>
		<title>Memory Mapped File Performance</title>
		<link>https://thargy.com/2014/03/memory-mapped-file-performance/</link>
		
		<dc:creator><![CDATA[thargy]]></dc:creator>
		<pubDate>Sat, 01 Mar 2014 13:46:03 +0000</pubDate>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Array.Copy]]></category>
		<category><![CDATA[LINQPad]]></category>
		<category><![CDATA[Memory Mapped File]]></category>
		<category><![CDATA[MemoryMappedViewAccessor]]></category>
		<category><![CDATA[MemoryMappedViewStream]]></category>
		<category><![CDATA[Performance]]></category>
		<guid isPermaLink="false">http://thargy.com/?p=456</guid>

					<description><![CDATA[In my last post I introduced Memory Mapped Files, and discussed how you could mark them as sparse.  Today, I would like to talk a little about performance.  Using LINQPad (my favourite tool!), I created a rough and ready test script which can be downloaded at the end of the article. The idea was to ...]]></description>
										<content:encoded><![CDATA[<div class="entry">
<p>In my <a title="Sparse Memory Mapped Files" href="http://thargy.com/2014/03/sparse-memory-mapped-files/" target="_blank" rel="noopener noreferrer">last post</a> I introduced <a title="Memory Mapped Files" href="https://docs.microsoft.com/en-us/dotnet/standard/io/memory-mapped-files?redirectedfrom=MSDN" target="_blank" rel="noopener noreferrer">Memory Mapped Files</a>, and discussed how you could mark them as <a title="Sparse Files" href="https://en.wikipedia.org/wiki/NTFS#Sparse_files" target="_blank" rel="noopener noreferrer">sparse</a>.  Today, I would like to talk a little about performance.  Using <a title="LINQPad" href="https://www.linqpad.net/" target="_blank" rel="noopener noreferrer">LINQPad</a> (my favourite tool!), I created a rough and ready test script which can be downloaded at the end of the article.</p>
<p>The idea was to check the raw read performance of getting an array of bytes from a <a title="Memory Mapped Files" href="https://docs.microsoft.com/en-us/dotnet/standard/io/memory-mapped-files?redirectedfrom=MSDN" target="_blank" rel="noopener noreferrer">memory mapped file</a>.  As a control I used <a title="Array.Copy" href="https://docs.microsoft.com/en-us/dotnet/api/system.array.copy?redirectedfrom=MSDN&amp;view=netframework-4.8" target="_blank" rel="noopener noreferrer">Array.Copy</a> to copy the same number of bytes from one</p>
<pre class="lang:c# decode:1 inline:1 ">byte[]</pre>
<p>to another.  I also was only interested in accessing the same block of memory each time, and took measurements after an initial read, the idea being that I&#8217;d expect the data to be in memory and not on disk.</p>
<p>There are two ways of accessing data on a memory mapped file &#8211; using a <a title="MemoryMappedViewStream" href="https://docs.microsoft.com/en-us/dotnet/api/system.io.memorymappedfiles.memorymappedviewstream?redirectedfrom=MSDN&amp;view=netframework-4.8" target="_blank" rel="noopener noreferrer">MemoryMappedViewStream</a> and an <a title="MemoryMappedViewAccessor" href="https://docs.microsoft.com/en-us/dotnet/api/system.io.memorymappedfiles.memorymappedviewaccessor?redirectedfrom=MSDN&amp;view=netframework-4.8" target="_blank" rel="noopener noreferrer">MemoryMappedViewAccessor</a>.  The former is optimised to provide sequential access (e.g. when reading or writing a block of data) and the later is optimised for random access reading and writing.</p>
<p>Another area of concern for me was to determine how important it was to hold onto the stream/accessor.  That is, what is the cost of creating the stream/accessor on demand, or keeping hold of the disposable object and using it repeatedly.  Clearly, it was highly likely that re-using the same stream/accessor was going to be faster, but doing so could complicate designs so quantifying the relative cost was useful.</p>
<p>You can run the code yourself, but here is the summary of my findings, where each figure represents a factor of how much slower each operation is.  &#8216;Single&#8217; indicates that multiple loops made use of the same view or accessor, whereas multiple indicates that a new view or accessor was created for each iteration:</p>
<table border="0" width="538" cellspacing="0" cellpadding="0">
<colgroup>
<col width="68" />
<col width="45" />
<col width="60" />
<col width="66" />
<col width="45" />
<col width="60" />
<col width="66" />
<col span="2" width="64" /> </colgroup>
<tbody>
<tr>
<td style="text-align: left;" rowspan="3" width="68" height="61">Block Size<br />
(bytes)</td>
<td style="text-align: center;" colspan="3" width="171">View Stream</td>
<td style="text-align: center;" colspan="3" width="171">Accessor</td>
<td style="text-align: center;" colspan="2" width="128">Accessor/Stream</td>
</tr>
<tr>
<td style="text-align: center;" colspan="2" height="20">vs. Array</td>
<td rowspan="2" width="66">Multiple/<br />
Single</td>
<td style="text-align: center;" colspan="2">vs. Array</td>
<td rowspan="2" width="66">Multiple/<br />
Single</td>
<td rowspan="2">Single</td>
<td rowspan="2">Multiple</td>
</tr>
<tr>
<td height="21">Single</td>
<td>Multiple</td>
<td>Single</td>
<td>Multiple</td>
</tr>
<tr>
<td align="right" height="20">32</td>
<td align="right">3.3</td>
<td align="right">400</td>
<td align="right">121</td>
<td align="right">12</td>
<td align="right">400</td>
<td align="right">33</td>
<td align="right">4</td>
<td align="right">1.01</td>
</tr>
<tr>
<td align="right" height="20">1024</td>
<td align="right">1.75</td>
<td align="right">127</td>
<td align="right">73</td>
<td align="right">120</td>
<td align="right">243</td>
<td align="right">2</td>
<td align="right">69</td>
<td align="right">1.9</td>
</tr>
<tr>
<td align="right" height="21">32768</td>
<td align="right">1.03</td>
<td align="right">9.7</td>
<td align="right">9</td>
<td align="right">163</td>
<td align="right">172</td>
<td align="right">1</td>
<td align="right">158</td>
<td align="right">17.6</td>
</tr>
</tbody>
</table>
<p>All these figures are approximate, and you&#8217;re results may vary but they can allow us to draw some general conclusions:</p>
<ol>
<li>Accessors are always slower than streams when reading/writing data sequentially, the difference gets worse as the size of data increases.  Therefore, performance can be greatly improved by always writing data sequentially and in large chunks, however the choice is less important for small amounts of data (less than a kilobyte).</li>
<li>There is a cost to creating and disposing accessors, this cost becomes acceptable for accessors when the size of the data being read is in the order of kilobytes, and quickly becomes negligible over 32K.  The benefit of keeping hold of a stream remains significant.</li>
<li>When reading a large stream the performance is equivalent to raw memory access.</li>
<li>The proportional cost of creating an accessor increases as the size of the buffer is increased, this is the opposite of creating streams &#8211; where the cost is fixed and therefore the relative cost decreases.</li>
<li>All of this needs to be taken alongside the reality that the slowest operation, reading 32K with a freshly created accessor, took a total of 0.49ms, that&#8217;s slow compared to the ~3ns required to copy a 32K
<pre class="lang:c# decode:1 inline:1 ">byte[]</pre>
<p>, but it&#8217;s certainly not slow in the grand scheme of things.</li>
</ol>
<p>These overall conclusions will hopefully help you when designing any systems that leverage <a title="Memory Mapped Files" href="https://docs.microsoft.com/en-us/dotnet/standard/io/memory-mapped-files?redirectedfrom=MSDN" target="_blank" rel="noopener noreferrer">memory mapped files</a>.</p>
<p>The <a href="https://gist.github.com/thargy/5a025aaae1924e5525afa3be053e0d16">code is availabvle as a Gist</a>, or can be downloaded using the button below:</p>
<p><a href='https://thargy.com/download/test-memory-mapped-file/?wpdmdl=722&refresh=6a0fd9a7cf9e01779423655'>        <div class="w3eden"><div class="link-btn light  pleft">    <div class="media">        <div class="pull-left wbt-left"><div class="wbt-icon">http://thargy.com/wp-content/plugins/download-manager/assets/file-type-icons/txt.png</div></div>        <div class="media-body text-left wbt-content"><strong class="ptitle">                Test Memory Mapped File            </strong>            <div style="font-size: 8pt;padding-top: 1px">Download <i style="margin: 4px 0 0 5px;opacity:0.5"                                                           class="fa fa-th-large"></i> 5.58 KB            </div>        </div>    </div></div><div style="clear: both;"></div></div><script>jQuery(function(){jQuery('.link-btn a.wpdm-download-link img').after('Download');jQuery('.link-btn a.wpdm-download-link img').remove();});</script></a></p>
</div>
<h3>Related Images:</h3>
<p> [<a href="https://thargy.com/2014/03/memory-mapped-file-performance/">See image gallery at thargy.com</a>] </p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">456</post-id>	</item>
		<item>
		<title>Sparse Memory Mapped Files</title>
		<link>https://thargy.com/2014/03/sparse-memory-mapped-files/</link>
					<comments>https://thargy.com/2014/03/sparse-memory-mapped-files/#comments</comments>
		
		<dc:creator><![CDATA[thargy]]></dc:creator>
		<pubDate>Sat, 01 Mar 2014 12:25:24 +0000</pubDate>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[COM]]></category>
		<category><![CDATA[Interop]]></category>
		<category><![CDATA[Memory Mapped Files]]></category>
		<category><![CDATA[NTFS]]></category>
		<category><![CDATA[Sparse]]></category>
		<category><![CDATA[Windows]]></category>
		<guid isPermaLink="false">http://thargy.com/?p=449</guid>

					<description><![CDATA[Memory mapped files are a powerful addition to the .NET framework in version 4.0.  They&#8217;ve been a key part of the windows Operating System since Windows 95, but using them required a working knowledge of COM Interop, as they weren&#8217;t exposed directly through the framework.  It&#8217;s well worth reading up on them, especially if you&#8217;re ...]]></description>
										<content:encoded><![CDATA[<div class="entry">
<p><a title="Memory mapped files" href="https://docs.microsoft.com/en-us/dotnet/standard/io/memory-mapped-files?redirectedfrom=MSDN" target="_blank" rel="noopener noreferrer">Memory mapped files</a> are a powerful addition to the .NET framework in version 4.0.  They&#8217;ve been a <a title="Managing Memory-Mapped Files" href="https://docs.microsoft.com/en-us/previous-versions/ms810613(v=msdn.10)?redirectedfrom=MSDN" target="_blank" rel="noopener noreferrer">key part of the windows Operating System since Windows 95</a>, but using them required a working knowledge of <a title="COM Interop" href="https://en.wikipedia.org/wiki/COM_Interop" target="_blank" rel="noopener noreferrer">COM Interop</a>, as they weren&#8217;t exposed directly through the framework.  It&#8217;s well worth reading up on them, especially if you&#8217;re considering working with files across multiple processes, etc., but one of their biggest features is how efficiently they let you interact with extremely large files.</p>
<p><a title="NTFS" href="https://en.wikipedia.org/wiki/NTFS" target="_blank" rel="noopener noreferrer">NTFS </a>has a feature called <a title="Sparse Files" href="https://docs.microsoft.com/en-us/windows/win32/fileio/sparse-files?redirectedfrom=MSDN" target="_blank" rel="noopener noreferrer">sparse files</a>, which is particularly useful with large files that mostly contain zero-data (that is where there are large blocks of zeroes in the file).  Combining memory mapped files with sparse files can be extremely powerful.  Unfortunately, .NET doesn&#8217;t expose this ability yet, so it&#8217;s back to good old <a title="COM Interop" href="https://en.wikipedia.org/wiki/COM_Interop" target="_blank" rel="noopener noreferrer">COM Interop</a>.  The following snippet will give you an extension method that can be applied to any <a title="FileStream" href="https://docs.microsoft.com/en-us/dotnet/api/system.io.filestream?redirectedfrom=MSDN&amp;view=netframework-4.8" target="_blank" rel="noopener noreferrer">FileStream</a> to turn the underlying file into a <a title="Sparse Files" href="https://docs.microsoft.com/en-us/windows/win32/fileio/sparse-files?redirectedfrom=MSDN" target="_blank" rel="noopener noreferrer">sparse file</a>.</p>
<pre class="lang:c# decode:true">public static class Extensions
{
	[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
	private static extern bool DeviceIoControl(
		SafeFileHandle hDevice,
		int dwIoControlCode,
		IntPtr InBuffer,
		int nInBufferSize,
		IntPtr OutBuffer,
		int nOutBufferSize,
		ref int pBytesReturned,
		[In] ref NativeOverlapped lpOverlapped
	);

	public static bool MarkAsSparseFile(FileStream fileStream)
	{
		int bytesReturned = 0;
		NativeOverlapped lpOverlapped = new NativeOverlapped();
		return DeviceIoControl(
			fileStream.SafeFileHandle,
			590020, //FSCTL_SET_SPARSE,
			IntPtr.Zero,
			0,
			IntPtr.Zero,
			0,
			ref bytesReturned,
			ref lpOverlapped);
	}
}</pre>
<p>There&#8217;s a great article about sparse files at <a title="Sparse files" href="http://www.flexhex.com/docs/articles/sparse-files.phtml" target="_blank" rel="noopener noreferrer">http://www.flexhex.com/docs/articles/sparse-files.phtml</a>, which is well worth a read.  One particular caveat of note is that once a file is marked as sparse, the operation cannot be undone, the only way to make it &#8216;not sparse&#8217; is to rebuild the file from scratch (i.e copy the data into a new file).  As such the best way to use the above is when you create the file initially:</p>
<pre class="lang:c# decode:true">using (FileStream f = File.Create(@"C:\MySparseFile.tmp"))
{
	// Try to mark file as sparse, if this fails then the SetLength will allocate the full file size.
	if (!MarkAsSparseFile(f))
		Log("Failed to create world as sparse file.");

	// Set file length
	f.SetLength(size);
	f.Close();
}</pre>
<p>Now we can create our <a title="Memory mapped files" href="https://docs.microsoft.com/en-us/dotnet/standard/io/memory-mapped-files?redirectedfrom=MSDN" target="_blank" rel="noopener noreferrer">memory mapped file</a> from our newly created sparse file:</p>
<pre class="lang:c# decode:true">using (MemoryMappedFile m = MemoryMappedFile.CreateFromFile(@"C:\MySparseFile.tmp"))
{
	// TODO Use our file!
}</pre>
<p>&nbsp;</p>
</div>
<h3>Related Images:</h3>
<p> [<a href="https://thargy.com/2014/03/sparse-memory-mapped-files/">See image gallery at thargy.com</a>] </p>
]]></content:encoded>
					
					<wfw:commentRss>https://thargy.com/2014/03/sparse-memory-mapped-files/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">449</post-id>	</item>
		<item>
		<title>Secret Diary of an Interviewer</title>
		<link>https://thargy.com/2014/01/secret-diary-of-an-interviewer/</link>
		
		<dc:creator><![CDATA[thargy]]></dc:creator>
		<pubDate>Sat, 18 Jan 2014 15:31:41 +0000</pubDate>
				<category><![CDATA[Careers]]></category>
		<category><![CDATA[Management]]></category>
		<guid isPermaLink="false">http://thargy.com/?p=444</guid>

					<description><![CDATA[We do a lot of interviews at Web Applications, especially with the launch of our Apprenticeship scheme.  Over the years I&#8217;ve seen the best and worst of what candidates bring to the table.  Unfortunately, there&#8217;s far more bad than good, and it&#8217;s so unnecessary. Every now and then I get invited to speak at conferences ...]]></description>
										<content:encoded><![CDATA[<div class="entry">
<p>We do a lot of interviews at <a title="Web Applications" href="https://www.koder.ly/" target="_blank" rel="noopener noreferrer">Web Applications</a>, especially with the launch of our <a title="Web Application&#039;s UK Apprenticeships" href="https://www.koder.ly/careers/" target="_blank" rel="noopener noreferrer">Apprenticeship scheme</a>.  Over the years I&#8217;ve seen the best and worst of what candidates bring to the table.  Unfortunately, there&#8217;s far more bad than good, and it&#8217;s so unnecessary.</p>
<p>Every now and then I get invited to speak at conferences and seminars about interview technique, and back in October I found myself speaking at the <a title="Engineering, Science &amp; Technology Fair" href="http://www.employers.manchester.ac.uk/" target="_blank" rel="noopener noreferrer">Engineering, Science &amp; Technology Fair</a> at <a title="Manchester Central" href="https://www.manchestercentral.co.uk/" target="_blank" rel="noopener noreferrer">Manchester Central</a>.  The <a title="University of Manchester" href="https://www.manchester.ac.uk/" target="_blank" rel="noopener noreferrer">University of Manchester</a> recorded it for their students to refer to and I&#8217;ve finally got my hands on a copy, so apologies for the poor quality.  If you&#8217;re <a title="Web Applications UK Recruitment" href="https://www.koder.ly/careers/" target="_blank" rel="noopener noreferrer">looking for a new job</a> I really hope you find this helpful, and if you&#8217;re applying for a job with us here then, to be frank, you&#8217;d be an idiot not to watch this!</p>
<p><iframe class="youtube-player" width="480" height="270" src="https://www.youtube.com/embed/dy6NK71UVZU?version=3&#038;rel=1&#038;showsearch=0&#038;showinfo=1&#038;iv_load_policy=1&#038;fs=1&#038;hl=en-GB&#038;autohide=2&#038;wmode=transparent" allowfullscreen="true" style="border:0;" sandbox="allow-scripts allow-same-origin allow-popups allow-presentation allow-popups-to-escape-sandbox"></iframe></p>
</div>
<h3>Related Images:</h3>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">444</post-id>	</item>
		<item>
		<title>&#8230; get in the queue.</title>
		<link>https://thargy.com/2013/08/get-in-the-queue/</link>
		
		<dc:creator><![CDATA[thargy]]></dc:creator>
		<pubDate>Sun, 11 Aug 2013 11:09:52 +0000</pubDate>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Generics]]></category>
		<category><![CDATA[Queue]]></category>
		<category><![CDATA[stack]]></category>
		<guid isPermaLink="false">http://thargy.com/?p=438</guid>

					<description><![CDATA[OK, so yesterday I returned with a really simple piece of code that&#8217;s convenient when building stack frames. After stacks, the next easiest/most convenient structure has to be the queue.  No surprise then that .NET has a similarly generic Queue  class. It seems appropriate to give it the same treatment &#8211; public class Queue&#60;T1, T2&#62; ...]]></description>
										<content:encoded><![CDATA[<div class="entry">
<p>OK, so yesterday I returned with a <a title="Stack ‘em up!" href="http://thargy.com/2013/08/stack-em-up/">really simple piece of code that&#8217;s convenient when building stack frames</a>.</p>
<p>After stacks, the next easiest/most convenient structure has to be <a title="Queue data structure" href="https://en.wikipedia.org/wiki/Queue_(data_structure)">the queue</a>.  No surprise then that .NET has a similarly generic </p>
<pre class="lang:c# decode:1 inline:1 " >Queue </pre>
<p> class.</p>
<p>It seems appropriate to give it the same treatment &#8211;</p>
<pre class="lang:c# decode:true ">public class Queue&lt;T1, T2&gt; : Queue&lt;Tuple&lt;T1, T2&gt;&gt;
{
    public void Enqueue(T1 item1, T2 item2)
    {
        Enqueue(new Tuple&lt;T1, T2&gt;(item1, item2));
    }
}

public class Queue&lt;T1, T2, T3&gt; : Queue&lt;Tuple&lt;T1, T2, T3&gt;&gt;
{
    public void Enqueue(T1 item1, T2 item2, T3 item3)
    {
        Enqueue(new Tuple&lt;T1, T2, T3&gt;(item1, item2, item3));
    }
}
public class Queue&lt;T1, T2, T3, T4&gt; : Queue&lt;Tuple&lt;T1, T2, T3, T4&gt;&gt;
{
    public void Enqueue(T1 item1, T2 item2, T3 item3, T4 item4)
    {
        Enqueue(new Tuple&lt;T1, T2, T3, T4&gt;(item1, item2, item3, item4));
    }
}
public class Queue&lt;T1, T2, T3, T4, T5&gt; : Queue&lt;Tuple&lt;T1, T2, T3, T4, T5&gt;&gt;
{
    public void Enqueue(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5)
    {
        Enqueue(new Tuple&lt;T1, T2, T3, T4, T5&gt;(item1, item2, item3, item4, item5));
    }
}
public class Queue&lt;T1, T2, T3, T4, T5, T6&gt; : Queue&lt;Tuple&lt;T1, T2, T3, T4, T5, T6&gt;&gt;
{
    public void Enqueue(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6)
    {
        Enqueue(new Tuple&lt;T1, T2, T3, T4, T5, T6&gt;(item1, item2, item3, item4, item5, item6));
    }
}
public class Queue&lt;T1, T2, T3, T4, T5, T6, T7&gt; : Queue&lt;Tuple&lt;T1, T2, T3, T4, T5, T6, T7&gt;&gt;
{
    public void Enqueue(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7)
    {
        Enqueue(new Tuple&lt;T1, T2, T3, T4, T5, T6, T7&gt;(item1, item2, item3, item4, item5, item6, item7));
    }
}
public class Queue&lt;T1, T2, T3, T4, T5, T6, T7, TRest&gt; : Queue&lt;Tuple&lt;T1, T2, T3, T4, T5, T6, T7, TRest&gt;&gt;
{
    public void Enqueue(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest)
    {
        Enqueue(new Tuple&lt;T1, T2, T3, T4, T5, T6, T7, TRest&gt;(item1, item2, item3, item4, item5, item6, item7, rest));
    }
}</pre>
<p>I won&#8217;t insult you with example usage, but hopefully I&#8217;ve saved someone some typing.</p>
</div>
<h3>Related Images:</h3>
<p> [<a href="https://thargy.com/2013/08/get-in-the-queue/">See image gallery at thargy.com</a>] </p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">438</post-id>	</item>
		<item>
		<title>Stack &#8217;em up!</title>
		<link>https://thargy.com/2013/08/stack-em-up/</link>
		
		<dc:creator><![CDATA[thargy]]></dc:creator>
		<pubDate>Sat, 10 Aug 2013 14:31:04 +0000</pubDate>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[stack]]></category>
		<guid isPermaLink="false">http://thargy.com/?p=427</guid>

					<description><![CDATA[OK, clearly I have been remiss in my bloging duties and owe you all some code.  To be fair, it&#8217;s because I&#8217;m head down developing a brand new platform that will form the basis of our future products and it really has been all go. One of the most fundamental structures in programming languages is ...]]></description>
										<content:encoded><![CDATA[<div class="entry">
<p>OK, clearly I have been remiss in my bloging duties and owe you all some code.  To be fair, it&#8217;s because I&#8217;m head down developing a brand new platform that will form the basis of our future products and it really has been all go.</p>
<p>One of the most fundamental structures in programming languages is <a title="The Stack abstract data type" href="https://en.wikipedia.org/wiki/Stack_(abstract_data_type)" target="_blank">the stack</a>.  It&#8217;s an insanely useful structure, particularly for analysing hierarchical data, but also for removing recursion from code (because recursion is oft times bad).</p>
<p>C# has a handy <a title="generic programming" href="https://en.wikipedia.org/wiki/Generic_programming" target="_blank">generic</a> </p>
<pre class="lang:c# decode:1 inline:1 " >Stack</pre>
<p>  class &#8211; which can be used like so-</p>
<pre class="lang:csharp decode:1 mixed:false " >Stack&lt;int&gt; stack = new Stack&lt;int&gt;();
stack.Push(1);
stack.Push(2);
Console.WriteLine(stack.Pop()); // Outputs: 2
Console.WriteLine(stack.Pop()); // Outputs: 1
</pre>
<p>Basically, you push things onto the top of the stack, and pop them off later.  It&#8217;s amazing what you can do with such a simple concept, but that&#8217;s not the topic of this post.</p>
<p>When you start doing more complex operations, you often find you want to put quite a bit of data onto the stack, rather than just a simple class.  I often find, in this particular scenario, it&#8217;s time to create a custom class/struct to hold the data.  However, sometimes, you just need something really simple.  It&#8217;s at times like those our old friend the Tuple comes in handy.  However, the code starts looking really unwieldy alarmingly quickly-</p>
<pre class="lang:c# decode:true">Stack&lt;Tuple&lt;int, string, bool&gt;&gt; stack = new Stack&lt;Tuple&lt;int, string, bool&gt;&gt;();
stack.Push(new Tuple&lt;int, string, bool&gt;(1, "One", false));
stack.Push(new Tuple&lt;int, string, bool&gt;(2, "Two", true));

Tuple&lt;int, string, bool&gt; frame = stack.Pop();
// Outputs: 2, Two, True
Console.WriteLine(string.Format("{0}, {1}, {2}", 
    frame.Item1,
    frame.Item2,
    frame.Item3));

frame = stack.Pop();
// Outputs: 1, One, False
Console.WriteLine(string.Format("{0}, {1}, {2}", 
    frame.Item1,
    frame.Item2,
    frame.Item3));</pre>
<p>We can solve this really easily though, by extending </p>
<pre class="lang:c# decode:1 inline:1 " >Stack</pre>
<p>  to support multiple values:</p>
<pre class="lang:c# decode:true">public class Stack&lt;T1, T2&gt; : Stack&lt;Tuple&lt;T1, T2&gt;&gt;
{
    public void Push(T1 item1, T2 item2)
    {
        Push(new Tuple&lt;T1, T2&gt;(item1, item2));
    }
}

public class Stack&lt;T1, T2, T3&gt; : Stack&lt;Tuple&lt;T1, T2, T3&gt;&gt;
{
    public void Push(T1 item1, T2 item2, T3 item3)
    {
        Push(new Tuple&lt;T1, T2, T3&gt;(item1, item2, item3));
    }
}
public class Stack&lt;T1, T2, T3, T4&gt; : Stack&lt;Tuple&lt;T1, T2, T3, T4&gt;&gt;
{
    public void Push(T1 item1, T2 item2, T3 item3, T4 item4)
    {
        Push(new Tuple&lt;T1, T2, T3, T4&gt;(item1, item2, item3, item4));
    }
}
public class Stack&lt;T1, T2, T3, T4, T5&gt; : Stack&lt;Tuple&lt;T1, T2, T3, T4, T5&gt;&gt;
{
    public void Push(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5)
    {
        Push(new Tuple&lt;T1, T2, T3, T4, T5&gt;(item1, item2, item3, item4, item5));
    }
}
public class Stack&lt;T1, T2, T3, T4, T5, T6&gt; : Stack&lt;Tuple&lt;T1, T2, T3, T4, T5, T6&gt;&gt;
{
    public void Push(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6)
    {
        Push(new Tuple&lt;T1, T2, T3, T4, T5, T6&gt;(item1, item2, item3, item4, item5, item6));
    }
}
public class Stack&lt;T1, T2, T3, T4, T5, T6, T7&gt; : Stack&lt;Tuple&lt;T1, T2, T3, T4, T5, T6, T7&gt;&gt;
{
    public void Push(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7)
    {
        Push(new Tuple&lt;T1, T2, T3, T4, T5, T6, T7&gt;(item1, item2, item3, item4, item5, item6, item7));
    }
}
public class Stack&lt;T1, T2, T3, T4, T5, T6, T7, TRest&gt; : Stack&lt;Tuple&lt;T1, T2, T3, T4, T5, T6, T7, TRest&gt;&gt;
{
    public void Push(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest)
    {
        Push(new Tuple&lt;T1, T2, T3, T4, T5, T6, T7, TRest&gt;(item1, item2, item3, item4, item5, item6, item7, rest));
    }
}</pre>
<p>Now we can write the same code in a much nicer way:</p>
<pre class="lang:c# decode:true">Stack&lt;int, string, bool&gt; stack = new Stack&lt;int, string, bool&gt;();
stack.Push(1, "One", false);
stack.Push(2, "Two", true);

var frame = stack.Pop();
// Outputs: 2, Two, True
Console.WriteLine(string.Format("{0}, {1}, {2}", 
    frame.Item1,
    frame.Item2,
    frame.Item3));

frame = stack.Pop();
// Outputs: 1, One, False
Console.WriteLine(string.Format("{0}, {1}, {2}", 
    frame.Item1,
    frame.Item2,
    frame.Item3));</pre>
<p>Simple, but very effective.  Let me know if it helps you out in the comments below.</p>
</div>
<h3>Related Images:</h3>
<p> [<a href="https://thargy.com/2013/08/stack-em-up/">See image gallery at thargy.com</a>] </p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">427</post-id>	</item>
		<item>
		<title>.NET fundamentals &#8211; the singleton pattern</title>
		<link>https://thargy.com/2013/06/net-fundamentals-singleton-pattern/</link>
		
		<dc:creator><![CDATA[thargy]]></dc:creator>
		<pubDate>Fri, 14 Jun 2013 23:01:49 +0000</pubDate>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[ConcurrentDictionary]]></category>
		<category><![CDATA[Singleton]]></category>
		<category><![CDATA[static]]></category>
		<guid isPermaLink="false">http://thargy.com/?p=374</guid>

					<description><![CDATA[For those interested in another sample of our in-house training here is a snippet where I introduce the singleton pattern: Related Images: [See image gallery at thargy.com]]]></description>
										<content:encoded><![CDATA[<div class="entry">
<p>For those interested in another sample of our in-house training here is a snippet where I introduce the singleton pattern:</p>
<p><iframe loading="lazy" class="youtube-player" width="480" height="270" src="https://www.youtube.com/embed/I8B8ir78hMY?version=3&#038;rel=1&#038;showsearch=0&#038;showinfo=1&#038;iv_load_policy=1&#038;fs=1&#038;hl=en-GB&#038;autohide=2&#038;wmode=transparent" allowfullscreen="true" style="border:0;" sandbox="allow-scripts allow-same-origin allow-popups allow-presentation allow-popups-to-escape-sandbox"></iframe></p>
</div>
<h3>Related Images:</h3>
<p> [<a href="https://thargy.com/2013/06/net-fundamentals-singleton-pattern/">See image gallery at thargy.com</a>] </p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">374</post-id>	</item>
		<item>
		<title>.NET fundamentals &#8211; an intro to structs</title>
		<link>https://thargy.com/2013/05/net-fundamentals-an-intro-to-structs/</link>
		
		<dc:creator><![CDATA[thargy]]></dc:creator>
		<pubDate>Thu, 09 May 2013 20:41:44 +0000</pubDate>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[struct stack]]></category>
		<guid isPermaLink="false">http://thargy.com/?p=368</guid>

					<description><![CDATA[Every couple of weeks I give an &#8216;off the cuff&#8217; talk on .NET fundamentals.  Its always fast paced, irreverent, opinionated and completely unprepared (you can tell). Aimed at our developers &#8211; as part of their continuous professional development &#8211; the 1hr+ talks are recorded and used as part of our training regimen. It&#8217;s not for ...]]></description>
										<content:encoded><![CDATA[<div class="entry">
<p>Every couple of weeks I give an &#8216;off the cuff&#8217; talk on .NET fundamentals.  Its always fast paced, irreverent, opinionated and completely unprepared (you can tell).</p>
<p>Aimed at our developers &#8211; as part of their continuous professional development &#8211; the 1hr+ talks are recorded and used as part of our training regimen.  It&#8217;s not for the feint hearted.</p>
<p>Every now and then our design team cuts them down to 15 minutes of raw ramblings to give people a taste of what its like being a developer at Web Apps.</p>
<p>The latest one, covering structs, is here:</p>
<p><iframe loading="lazy" class="youtube-player" width="480" height="270" src="https://www.youtube.com/embed/HEjfKReFDcg?version=3&#038;rel=1&#038;showsearch=0&#038;showinfo=1&#038;iv_load_policy=1&#038;fs=1&#038;hl=en-GB&#038;autohide=2&#038;wmode=transparent" allowfullscreen="true" style="border:0;" sandbox="allow-scripts allow-same-origin allow-popups allow-presentation allow-popups-to-escape-sandbox"></iframe></p>
</div>
<h3>Related Images:</h3>
<p> [<a href="https://thargy.com/2013/05/net-fundamentals-an-intro-to-structs/">See image gallery at thargy.com</a>] </p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">368</post-id>	</item>
		<item>
		<title>The Entwistle Payoff</title>
		<link>https://thargy.com/2012/11/the-entwistle-payoff/</link>
		
		<dc:creator><![CDATA[thargy]]></dc:creator>
		<pubDate>Mon, 12 Nov 2012 20:51:19 +0000</pubDate>
				<category><![CDATA[Management]]></category>
		<category><![CDATA[BBC]]></category>
		<category><![CDATA[Entwistle]]></category>
		<category><![CDATA[George]]></category>
		<category><![CDATA[Pay off]]></category>
		<guid isPermaLink="false">http://thargy.com/?p=359</guid>

					<description><![CDATA[So the current BBC naval gazing is kind of getting old, but today&#8217;s public outcry on the reported £450k pay off to the outgoing Director General of the BBC raises the kind of questions that I can&#8217;t resist letting pass without comment. What has driven me to write this post (on my iPhone no less) ...]]></description>
										<content:encoded><![CDATA[<div class="entry">
<p><a href="https://en.wikipedia.org/wiki/George_Entwistle"></a>So the current BBC naval gazing is kind of getting old, but today&#8217;s public outcry on the reported £450k pay off to the outgoing Director General of the BBC raises the kind of questions that I can&#8217;t resist letting pass without comment.</p>
<p>What has driven me to write this post (on my iPhone no less) is the ignorance of the ministers and MPs concerned. The reality being that this particular mess is likely entirely of their causing.</p>
<p>Over the last decade the Employment Tribunal has become so skewed and one sided against employers that dismissing anyone is nearly impossible, particularly anyone who has any claim to continuous service. Entwistle, as a career Beeber, was an untouchable. Moreover, he was clearly a politically expedient scapegoat &#8211; being in post for a mere 55 days, he was only as personally responsible as the vast array of Senior Managers drawing huge salaries from a typically top heavy publicly funded institution. His crime was that of too many bureaucrats, avoiding decisions rather than making them.</p>
<p>So to the £450k (an amount that exceeds my career earnings), not a bad hall for a 55 day stint. The Chair of the BBC Trust, Chris Patton, has revealed that the Trust expressed its concern to Entwistle on the Saturday and made it clear that they were considering his dismissal. At this point very few outcomes remained. In such a position Entwistle would find it near impossible to return to a place where he enjoyed the trusts confidence, had nothing happened, over time he would have been forced out, or at least edged out.</p>
<p>Having the threat of dismissal over his head Entwistle could resign and immediately claim constructed dismissal. In the modern world he would have won, and the BBC would have paid out a full severance package, plus loss of earnings, potential damages and legal fees. The mess would have been significant, the BBC would sustain further damage to its reputation, and the costs would have been greater than those of a straight dismissal as he had a contract which required the £450k severance amount.</p>
<p>What happened (probably!) is a confidential voluntary agreement. These are the norm these days, as businesses do not win at tribunal. Instead a business pays off the leaver, letting them resign, so as to avoid a tribunal and its associated costs. By its very nature the existence of the agreement can never be revealed by either party. This lets the BBC remove the man they shouldn&#8217;t have appointed, and to move on, without fear of repercussion.</p>
<p>It is modern day piracy and it occurs daily across the country. The only people that get these agreements are, in my bitter experience, the same selfish, manipulative, devious leeches that deserve them the least. That said it is a foolish executive that willingly faces a tribunal no matter how true their cause. Tragically, even winning at tribunal is entirely Pyrrhic, and victory is never guaranteed in the skewed halls of &#8216;justice&#8217;.</p>
<p>So don&#8217;t criticise the BBC for being pragmatic. In reality the £450k has saved the public purse a future pay out that would undoubtedly have been worse. Criticise the weak executive for appointing Entwistle in the first place and criticise the government for creating a tribunal system that believes the &#8216;right to work&#8217; comes independent of a &#8216;responsibility to work&#8217;. Criticise a contract for having a one year severance clause, even criticise the size of the salary for an &#8216;honourable man&#8217;.</p>
<p>As for Mr Entwistle, we should judge him by the amount of money he draws down. I suspect he&#8217;ll take every penny, despite being so &#8216;honourable&#8217;. I hope that in a similar situation I&#8217;d have the moral fortitude to take what I deserve morally and not what I may be &#8216;entitled&#8217; too, but how many of us would honestly walk away from such a pay out, after all he no longer has to clean up the mess that&#8217;s left.</p>
<p>The way these things work, I suspect Mr Entwistle will appear on some board somewhere in a few months when people stop paying attention.</p>
</div>
<h3>Related Images:</h3>
<p> [<a href="https://thargy.com/2012/11/the-entwistle-payoff/">See image gallery at thargy.com</a>] </p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">359</post-id>	</item>
		<item>
		<title>The hidden secret of the Concurrent Dictionary</title>
		<link>https://thargy.com/2012/09/the-hidden-secret-of-the-concurrent-dictionary/</link>
		
		<dc:creator><![CDATA[thargy]]></dc:creator>
		<pubDate>Fri, 21 Sep 2012 21:07:00 +0000</pubDate>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Collections]]></category>
		<category><![CDATA[Concurrency]]></category>
		<category><![CDATA[Concurrent Dictionary]]></category>
		<category><![CDATA[Interfaces]]></category>
		<category><![CDATA[Source code]]></category>
		<category><![CDATA[Symbols]]></category>
		<category><![CDATA[Thread safety]]></category>
		<guid isPermaLink="false">http://thargy.com/?p=347</guid>

					<description><![CDATA[When it comes to my favourite ‘new*’ classes in the .NET BCL, one of my top ten is definitely the ConcurrentDictionary .  So much so, that (after IEnumerable) it’s probably one of the classes I go back to most frequently to solve any particular problem (particularly caches). I still remember the frustration and failure I ...]]></description>
										<content:encoded><![CDATA[<div class="entry">
<p>When it comes to my favourite ‘new<a href="#Footnote"><sup>*</sup></a>’ classes in the .NET <a title="Base Class Libraries" href="https://en.wikipedia.org/wiki/Base_Class_Library">BCL</a>, one of my top ten is definitely the <a href="https://docs.microsoft.com/en-us/dotnet/api/system.collections.concurrent.concurrentdictionary-2?redirectedfrom=MSDN&amp;view=netframework-4.8">ConcurrentDictionary</a> .  So much so, that (after <a href="https://docs.microsoft.com/en-us/dotnet/api/system.collections.ienumerable?redirectedfrom=MSDN&amp;view=netframework-4.8">IEnumerable</a>) it’s probably one of the classes I go back to most frequently to solve any particular problem (particularly caches).</p>
<p>I still remember the frustration and failure I felt when I realised my own lovingly crafted solution to the problem of concurrent dictionaries was so enfeebled (particularly in performance, but also design) by this truly beautifully crafted class, and it didn’t take me long before I turned the power of reflection onto the class to unlock it’s dirty little secrets.  This is one of those gems that was written by the smarter guys at Microsoft, trust me they didn’t write everything in the BCL!</p>
<p>So it was with huge surprise that, a month or two ago, this Wunder-Klasse revealed another little beauty from behind its polished exterior.  The concurrent dictionary is fantastic for storing singular values in, but what happen when I want to store something more complex, in particular, an enumeration?  My solution was to create a ConcurrentLookup that implements <a href="https://docs.microsoft.com/en-us/dotnet/api/system.linq.ilookup-2?redirectedfrom=MSDN&amp;view=netframework-4.8">ILookup</a>.  I’d like to revisit the solution in a later post, but for now, let’s talk about what I discovered…</p>
<p>You see, ultimately the ‘standard’ public methods of the <a href="https://docs.microsoft.com/en-us/dotnet/api/system.collections.concurrent.concurrentdictionary-2?redirectedfrom=MSDN&amp;view=netframework-4.8">ConcurrentDictionary</a> only get you so far before you come up against a big problem.  When removing a key, how do I make sure it only get’s removed if the value is what I think it is?</p>
<p>Well, the answer (in brief) is best illustrated by some example code &#8211;</p>
<pre class="lang:csharp decode:1 mixed:false ">// Create the dictionary
ConcurrentDictionary&lt;int, int&gt; dictionary = new ConcurrentDictionary&lt;int, int&gt;();

// Add [1, 2] and [2, 3]
dictionary.GetOrAdd(1, 2);
dictionary.GetOrAdd(2, 3);

// This will succeed
Assert.IsTrue(((ICollection&lt;KeyValuePair&lt;int, int&gt;&gt;) dictionary)
.Remove(new KeyValuePair&lt;int, int&gt;(1, 2)));

// Let's get the value from 2 and confirm it's 3.
int value;
dictionary.TryGetValue(2, out value);

Assert.AreEqual(value, 3);

// Meanwhile, imagine this runs on another thread...
dictionary.AddOrUpdate(2, 4, (k, v) =&gt; 4);

// This remove will fail as value still equals 3, but the dictionary now contains 4!
Assert.IsFalse(((ICollection&lt;KeyValuePair&lt;int, int&gt;&gt;)dictionary)
.Remove(new KeyValuePair&lt;int, int&gt;(2, value)));

// The dictionary keeps it's key nice and safe.
Assert.IsTrue(dictionary.ContainsKey(2));</pre>
<p>This little horror shows that by casting the dictionary to one of its interfaces you can access an underused interface method explicitly.</p>
<p>I’ve known from day zero that <a href="https://docs.microsoft.com/en-us/dotnet/api/system.collections.concurrent.concurrentdictionary-2?redirectedfrom=MSDN&amp;view=netframework-4.8">ConcurrentDictionary</a> implements the <a href="https://docs.microsoft.com/en-us/dotnet/api/system.collections.icollection?redirectedfrom=MSDN&amp;view=netframework-4.8">ICollection</a> interface for the corresponding <a href="https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.keyvaluepair-2?redirectedfrom=MSDN&amp;view=netframework-4.8">KeyValuePair</a>, but it wasn’t until I was snooping around inside the source code that I stumbled across the private <span class="lang:c# decode:true  crayon-inline ">TryRemoveInternal</span>  method, that had a mysterious <span class="lang:c# decode:true  crayon-inline ">matchValue</span>  parameter.  It was a short hop to putting two and two together.  The <a href="https://docs.microsoft.com/en-us/dotnet/api/system.collections.concurrent.concurrentdictionary-2?redirectedfrom=MSDN&amp;view=netframework-4.8">method is technically in MSDN</a>, but it’s not something you’d spot and the implications are not particularly obvious.  The fact that the designers chose to implement the method explicitly so that it wouldn’t be accessible without casting, is normally a hint that it is not a good idea to use it.  In fact, the BCL is littered with examples where such methods throw an exception, however, this one is designed to work as advertised, but you’d never know if Microsoft didn’t publish the source so readily.</p>
<p>Just another good reason to spend a bit of time digging deeper.</p>
<p>I hope this little gem solves a problem for you today if it does, let me know!</p>
<p><span style="font-size: xx-small;"><a name="Footnote"></a><sup>*</sup> ‘New’ as in it wasn’t in the first version of .NET I ever used!</span></p>
</div>
<h3>Related Images:</h3>
<p> [<a href="https://thargy.com/2012/09/the-hidden-secret-of-the-concurrent-dictionary/">See image gallery at thargy.com</a>] </p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">347</post-id>	</item>
		<item>
		<title>Developing a career</title>
		<link>https://thargy.com/2012/09/developing-a-career/</link>
					<comments>https://thargy.com/2012/09/developing-a-career/#comments</comments>
		
		<dc:creator><![CDATA[thargy]]></dc:creator>
		<pubDate>Fri, 21 Sep 2012 06:00:00 +0000</pubDate>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Careers]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Management]]></category>
		<guid isPermaLink="false">http://thargy.com/?p=340</guid>

					<description><![CDATA[Well it’s been a while since my last post, frankly I’ve been heads down in a code rush (maybe I’ll let you in on it a little later), so I figured for my first post back I best make it a big one.  Following, from the success of my guest lecture at Manchester, I was ...]]></description>
										<content:encoded><![CDATA[<div class="entry">
<p>Well it’s been a while since my last post, frankly I’ve been heads down in a code rush (maybe I’ll let you in on it a little later), so I figured for my first post back I best make it a big one.  Following, from the success of my <a href="http://thargy.com/2012/04/delivering-code-as-a-team-2/">guest lecture at Manchester</a>, I was invited to speak to the students at Salford University.  Whenever I manage to trap someone within ear shot I can’t help but bombard them with my views on education, let’s just say it’s something I’m genuinely passionate about, so the theme was similar to my last one.  Hopefully though, it was more focussed, as instead of trying to cover too much I zoomed in on talking about a career in IT.</p>
<p>It’s in my nature to stimulate debate, and I’m a sucker for throwing in the odd controversial comment to garner a reaction, but my motivation is an honest one.  I genuinely believe the best course of action for a graduate developer is to find a job where they are inspired by their peers to become the best they can be.  In my experience, that doesn’t come from being the ‘<a href="https://www.igloocoder.com/2009/04/23/The-Hero-Developer/">hero developer</a>’ in a one man team, there’s a place for such people, but it’s not working for me.  The <a href="https://www.phrases.org.uk/meanings/268025.html">real greats stand on the shoulders of giants</a>.</p>
<p>Anyway, it was literally standing room only at Salford and the nearly ninety strong cohort of students (from all years) seemed genuinely interested as it took me a good half an hour to get away after I’d finished.  I’ve included the video below for everyone who missed it, hopefully it will encourage more graduates to seek out careers working with people who will inspire them.</p>
<p><iframe loading="lazy" class="youtube-player" width="480" height="270" src="https://www.youtube.com/embed/FXTzxYp_xmU?version=3&#038;rel=1&#038;showsearch=0&#038;showinfo=1&#038;iv_load_policy=1&#038;fs=1&#038;hl=en-GB&#038;autohide=2&#038;wmode=transparent" allowfullscreen="true" style="border:0;" sandbox="allow-scripts allow-same-origin allow-popups allow-presentation allow-popups-to-escape-sandbox"></iframe></p>
</div>
<h3>Related Images:</h3>
]]></content:encoded>
					
					<wfw:commentRss>https://thargy.com/2012/09/developing-a-career/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">340</post-id>	</item>
		<item>
		<title>Colorado, a tale of two tragedies</title>
		<link>https://thargy.com/2012/07/colorado-a-tale-of-two-tragedies/</link>
					<comments>https://thargy.com/2012/07/colorado-a-tale-of-two-tragedies/#comments</comments>
		
		<dc:creator><![CDATA[thargy]]></dc:creator>
		<pubDate>Fri, 20 Jul 2012 15:24:00 +0000</pubDate>
				<category><![CDATA[African Childrens' Choir]]></category>
		<category><![CDATA[Chamber of Commerce]]></category>
		<category><![CDATA[Management]]></category>
		<category><![CDATA[Personal]]></category>
		<category><![CDATA[African Childrens Choir]]></category>
		<category><![CDATA[Colorado]]></category>
		<category><![CDATA[Colorado Springs]]></category>
		<category><![CDATA[Dark Knight Rises]]></category>
		<category><![CDATA[Denver]]></category>
		<category><![CDATA[Oldham]]></category>
		<category><![CDATA[Parker]]></category>
		<category><![CDATA[September 11]]></category>
		<category><![CDATA[Twin Towers]]></category>
		<category><![CDATA[Web Applications UK]]></category>
		<category><![CDATA[Web Applications US]]></category>
		<guid isPermaLink="false">http://thargy.com/?p=329</guid>

					<description><![CDATA[The first time I came to this great state was in September 2001.&#160; The first time I came to Denver was to visit the airport on 10 September 2001.&#160; The 18th African Children’s Choir were set to fly back to West Africa, via Belfast and Choir 19 (that I was chaperoning) met up with them ...]]></description>
										<content:encoded><![CDATA[<div class="entry">
<p><img data-recalc-dims="1" loading="lazy" decoding="async" style="display: inline; float: right" align="right" src="https://i0.wp.com/www.thelifeofluxury.com/images/albuquerque_international_balloon_fiesta_1.jpg?resize=240%2C160" width="240" height="160">The first time I came to this great state was in September 2001.&nbsp; The first time I came to Denver was to visit <a href="https://www.flydenver.com/" target="_blank" rel="noopener noreferrer">the airport</a> on 10 September 2001.&nbsp; The 18th <a href="https://africanchildrenschoir.com/" target="_blank" rel="noopener noreferrer">African Children’s Choir</a> were set to fly back to West Africa, via Belfast and Choir 19 (that I was chaperoning) met up with them to hand over some equipment and say goodbye.&nbsp; We had a concert that evening in Colorado Springs but went with the choir to say goodbye.</p>
<p>A month before we had been in Albuquerque, New Mexico.&nbsp; I had stayed with a wonderful host family, a brother and sister, and one morning I awoke to see a sky full of 750 hot air balloons, as the <a href="https://en.wikipedia.org/wiki/Albuquerque_International_Balloon_Fiesta" target="_blank" rel="noopener noreferrer">Albuquerque International Balloon Fiesta</a> got under way.</p>
<p>As always we were performing a concert in a local church, and I always made a point of helping the local sound engineers out with tuning, repairs and set up – most are volunteers and always appreciated the help.&nbsp; This time I struck gold, as the engineer was actually a registered flight instructor and a jumbo pilot for one of the major airlines.&nbsp; Before I knew it I was in the cockpit of a Cessna flying over the New Mexico plains.&nbsp; I often repeat this story to young people as being mostly blind in one eye I can ‘never be an airplane pilot’, but on that day in 2001 I was just that.</p>
<p>A month later though, I was standing at the gate waving goodbye to Choir 18.&nbsp; Airports in America were no different to bus stations, it was so different to Heathrow or UK airports were we lived under the shadow of the IRA bombings.&nbsp; It was friendly and fun.</p>
<p><img loading="lazy" decoding="async" style="display: inline; float: left" alt="File:WTC-remnant highres.jpg" align="left" src="https://upload.wikimedia.org/wikipedia/commons/thumb/f/f7/WTC-remnant_highres.jpg/393px-WTC-remnant_highres.jpg" width="200" height="305">Choir 18’s flight was just past the point of no return when <a href="https://en.wikipedia.org/wiki/September_11_attacks" target="_blank" rel="noopener noreferrer">the planes hit the Twin Towers</a>, so they weren’t turned around and made it to Belfast.</p>
<p>The next few weeks in Colorado will remain with me for ever.&nbsp; I couldn’t go a night without a host family asking me why ‘everyone hated America so much’.&nbsp; It was a country waking up to the idea that they weren’t universally loved, that there were people out there that would do them harm, and like most people there initial reaction was horror and a genuine fear that meant they had no concept of the scale of the issue.&nbsp; The next attack could come at any second, they were in a war they don’t remember entering.&nbsp; In 2001 you would rarely see any news about the world outside the US, by October that all changed.&nbsp; The conversations I had were haunting, painful, people were genuinely scared.</p>
<p>During that time, I fell in love with Colorado, and when we left to continue our tour in Utah, the memories of those conversations and the place stuck with me.&nbsp; A beautiful state, with beautiful people.</p>
<p>Ten years later, I was in a completely different life.&nbsp; Instead of a volunteer sound engineer with the <a href="https://africanchildrenschoir.com/" target="_blank" rel="noopener noreferrer">African Children’s Choir</a>, I was Chief Executive of <a href="https://www.koder.ly/" target="_blank" rel="noopener noreferrer">Web Applications UK</a> – a rapidly growing IT company expanding into the US.&nbsp; When the question came as to where we would base our new head office, Colorado was always going to be first choice.&nbsp; We came out in May 2011 and stayed in Colorado Springs for the first time since that 2001 trip, and I fell in love with the state once again.</p>
<p>Today we’re back signing paperwork and preparing the final steps of launching <a href="https://www.koder.ly/" target="_blank" rel="noopener noreferrer">Web Applications US</a>.&nbsp; It’s and arduous complex process, countries don’t make it as easy as possible for foreigners to form businesses and create jobs.&nbsp; Vivienne and I are staying in Denver for the first time since I was here with the Choir.&nbsp; Late last night a young man walked into a midnight premier of “<a href="http://www.thedarkknightrises.com/" target="_blank" rel="noopener noreferrer">The Dark Knight Rises</a>” and <a href="https://www.bbc.co.uk/news/world-us-canada-18921492" target="_blank" rel="noopener noreferrer">shot and injured seventy men, women and children</a>, twelve of them died, and a number remain in critical condition as I write.&nbsp; The cinema is just down the road from where we’re staying, and once again I find myself in the heart of a community struggling to come to terms with inexplicable tragedy.</p>
<p>A <a href="https://www.theguardian.com/world/2012/jul/20/colorado-shooting-bloomberg-obama-romney" target="_blank" rel="noopener noreferrer">lot is being said about gun control</a> and <a href="https://en.wikipedia.org/wiki/Second_Amendment_to_the_United_States_Constitution" target="_blank" rel="noopener noreferrer">second amendment rights</a>.&nbsp; The media is <a href="https://www.washingtontimes.com/communities/" target="_blank" rel="noopener noreferrer">obsessed with the gunman and his potential motives and wild stories are flying around</a>.&nbsp; The scale of the tragedy is growing with each fresh announcement, and people are reeling.&nbsp; I’ll leave those conversations for others, instead I want to focus on the two things that made me fall in love with Colorado all those years ago.&nbsp; The people and the place.</p>
<p>The Coloradoan spirit is indomitable, they will reel, they will mourn, they will grieve, but they will ultimately survive.&nbsp; The night of the tragedy I was in <a href="http://parkeronline.org/" target="_blank" rel="noopener noreferrer">Parker</a> meeting with members of the <a href="http://www.parkerchamber.com/" target="_blank" rel="noopener noreferrer">Parker Chamber of Commerce</a>.&nbsp; We wanted to meet business men and women from the town to get a sense of the spirit of the place.&nbsp; <a href="https://www.koder.ly/" target="_blank" rel="noopener noreferrer">Web Applications UK</a> is committed to Oldham and it’s local community, it defines the kind of business we want to be.&nbsp; For <a href="https://www.koder.ly/" target="_blank" rel="noopener noreferrer">Web Applications US</a> we want to ensure that same anchor to the local community exists.</p>
<p>The people I found weren’t suspicious, unfriendly, wary.&nbsp; They were warm, welcoming and kind.&nbsp; For a state and a community that has lived through <a href="https://en.wikipedia.org/wiki/Columbine_High_School_massacre" target="_blank" rel="noopener noreferrer">Columbine</a>, <a href="https://en.wikipedia.org/wiki/September_11_attacks" target="_blank" rel="noopener noreferrer">September 11</a> and now the <a href="https://en.wikipedia.org/wiki/Aurora_shooting" target="_blank" rel="noopener noreferrer">Aurora Shooting</a>, I have no doubt that the people will remain true to themselves and to their spirit.</p>
<p>Finally, I fell in love with the place.&nbsp; The beautiful Rockies, the lakes, rivers and streams, the rolling hills and grasslands; Colorado is one of the most beautiful places in the entire world.&nbsp; No crazed gunman will ever change that.&nbsp; When <a href="https://www.koder.ly/" target="_blank" rel="noopener noreferrer">Web Applications US</a> finally opens shop fully, it will have a beautiful home and employ beautiful people.</p>
<p><img loading="lazy" decoding="async" style="display: block; float: none; margin-left: auto; margin-right: auto" alt="File:Tenmile Fletcher Group.jpg" src="https://upload.wikimedia.org/wikipedia/commons/thumb/2/2e/Tenmile_Fletcher_Group.jpg/800px-Tenmile_Fletcher_Group.jpg" width="640" height="424"></p>
</div>
<h3>Related Images:</h3>
<p> [<a href="https://thargy.com/2012/07/colorado-a-tale-of-two-tragedies/">See image gallery at thargy.com</a>] </p>
]]></content:encoded>
					
					<wfw:commentRss>https://thargy.com/2012/07/colorado-a-tale-of-two-tragedies/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">329</post-id>	</item>
		<item>
		<title>Jubilation</title>
		<link>https://thargy.com/2012/06/jubilation/</link>
		
		<dc:creator><![CDATA[thargy]]></dc:creator>
		<pubDate>Sun, 24 Jun 2012 16:40:06 +0000</pubDate>
				<category><![CDATA[Chamber of Commerce]]></category>
		<category><![CDATA[Management]]></category>
		<category><![CDATA[Church]]></category>
		<category><![CDATA[Diamond]]></category>
		<category><![CDATA[Elizabeth]]></category>
		<category><![CDATA[Ferrantis]]></category>
		<category><![CDATA[Jubilee]]></category>
		<category><![CDATA[Oldham]]></category>
		<category><![CDATA[Queen]]></category>
		<guid isPermaLink="false">http://thargy.com/?p=323</guid>

					<description><![CDATA[When it comes to the Queen, I’m a big fan.&#160; It’s become fashionable to mock the pomp and circumstance and to view her Highness as a dusty old relic of a bygone age, but to do so is to misrepresent a monarch that has done more to modernise and adapt than any predecessor – and ...]]></description>
										<content:encoded><![CDATA[<div class="entry">
<p><img data-recalc-dims="1" decoding="async" style="display: inline; float: right" alt="Queen's Diamond Jubilee logo" align="right" src="https://i0.wp.com/web.archive.org/web/20131226121714/http%3A//www.thediamondjubilee.org/profiles/dj/themes/dj/images/diamond-jubilee-logo.gif">When it comes to the Queen, I’m a big fan.&nbsp; It’s become fashionable to mock the pomp and circumstance and to view her Highness as a dusty old relic of a bygone age, but to do so is to misrepresent a monarch that has done more to modernise and adapt than any predecessor – and she’s had to, reigning through the Commonwealth’s must turbulent and transitional period.</p>
<p>When asked to attend Oldham’s Jubilee celebration at Oldham Parish Church I jumped at the opportunity.&nbsp; I was hugely privileged to represent Oldham Business and light a candle, alongside the Lord Lieutenant of Manchester and Mayor of Oldham.&nbsp; A last minute addition also saw me representing one element of life in borough when I got to present two parts of a PC as symbols of Oldham’s history as the first town to manufacture and build computers at Ferrantis.&nbsp; I had a quick look as I took my seat, and both were PCI-133 cards, one a modem (circa 2003) and one an aging SCSI connector (circa 2004).</p>
<p>Earlier in the day we hosted the Olympic Torch on it’s way around the country in advance of the upcoming games.&nbsp; Just like the Queen it’s easy to point at Oldham and see a town of past glories, of little relevance in the modern world.&nbsp; Cynics bore me with their lack of imagination!&nbsp; When I see Oldham, I see a town full of talented and great people, full of optimism about our collective future.&nbsp; These new Oldhamers are the only people I want to associate with.</p>
<p>As the Oldham Choir and Oldham Music Centre Brass Ensemble blasted out Handel’s “Zadok the Priest” I was taken back to a time when community mattered and coming together in acts of celebration were commonplace.&nbsp; Too easily we sit at home throwing stones when what’s needed is a willingness to step out of our comfort zones and work together to make something truly special.&nbsp; If our Queen has taught us anything, it’s that a life dedicated to service and quiet humility can survive the stones and arrows of the harshest critics, and that determination can bring about transformation in seemingly immutable institutions.</p>
<p>God save our Queen, long to reign over us!</p>
</div>
<h3>Related Images:</h3>
<p> [<a href="https://thargy.com/2012/06/jubilation/">See image gallery at thargy.com</a>] </p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">323</post-id>	</item>
		<item>
		<title>Leadership</title>
		<link>https://thargy.com/2012/06/leadership/</link>
					<comments>https://thargy.com/2012/06/leadership/#comments</comments>
		
		<dc:creator><![CDATA[thargy]]></dc:creator>
		<pubDate>Fri, 22 Jun 2012 21:20:52 +0000</pubDate>
				<category><![CDATA[Chamber of Commerce]]></category>
		<category><![CDATA[Management]]></category>
		<category><![CDATA[Autonomy]]></category>
		<category><![CDATA[Cohesion]]></category>
		<category><![CDATA[Decisiveness]]></category>
		<category><![CDATA[Drive]]></category>
		<category><![CDATA[Leadership]]></category>
		<category><![CDATA[Mastery]]></category>
		<category><![CDATA[Motivation]]></category>
		<category><![CDATA[Opportunism]]></category>
		<category><![CDATA[Persistence]]></category>
		<category><![CDATA[Purpose]]></category>
		<category><![CDATA[RSA]]></category>
		<category><![CDATA[Service]]></category>
		<guid isPermaLink="false">http://thargy.com/?p=317</guid>

					<description><![CDATA[Today I had the privilege of addressing the graduating cohort of about forty-five students and their police trainers from the Natural Born Leader’s programme being run by Greater Manchester Police.  This great programme takes young people on a week-long course to develop their natural leadership skills. The speaker before me was Duane Bryan, who was a ...]]></description>
										<content:encoded><![CDATA[<div class="entry">
<p><img data-recalc-dims="1" loading="lazy" decoding="async" style="display: inline; float: right;" src="https://i0.wp.com/web.archive.org/web/20140917181557/http%3A//static.bbci.co.uk/programmeimages/528xn/images/live/p00pynl3.jpg?resize=160%2C240" alt="Duane Bryan" width="160" height="240" align="right" /></p>
<p>Today I had the privilege of addressing the graduating cohort of about forty-five students and their police trainers from the Natural Born Leader’s programme being run by Greater Manchester Police.  This great programme takes young people on a week-long course to develop their natural leadership skills.</p>
<p>The speaker before me was <a href="https://uk.linkedin.com/in/duane-bryan-0673584a" target="_blank" rel="noopener noreferrer">Duane Bryan</a>, who was a candidate on this years ‘The Apprentice’ and he talked about his experiences on Alan Sugar&#8217;s show.</p>
<p>I was asked to explain how I had ended up as a business leader and to wrap up the week for the students by summing up my thoughts on leadership.</p>
<p>Leadership ultimately relies on an ability to understand what drives people, and I made reference to one of my favourite animations from the <a href="https://www.thersa.org/" target="_blank" rel="noopener noreferrer">RSA</a> “<a href="https://www.youtube.com/watch?v=u6XAPnuFjJc&amp;feature=youtu.be" target="_blank" rel="noopener noreferrer">Drive: The surprising truth about what motivates us</a>”.</p>
<p>In brief, I asserted that people are motivated by 3 things (the alternative <a href="https://en.wikipedia.org/wiki/Positive_mental_attitude" target="_blank" rel="noopener noreferrer">PMA</a> definition):</p>
<p><strong><em>P</em>urpose</strong> – the belief that what they are doing is for a reason and will ultimately have impact.<br />
<strong><em>M</em>astery</strong> – the ability to continue to improve to a point of mastering a skill.<br />
<strong><em>A</em>utonomy</strong> – the authority to make the decisions required to achieve your goals.</p>
<p>And leaders display 5 key qualities:</p>
<p><strong>Cohesion</strong> – the ability to inspire a group of people towards a common purpose.<br />
<strong>Decisiveness</strong> – the acceptance of the value of failure, empowering a leader to make decisions.<br />
<strong>Persistence</strong> – the determination to give strategies enough time to succeed.<br />
<strong>Opportunism</strong> – the ability to recognise and grasp opportunities as they present themselves.<br />
<strong>Service</strong> – the genuine desire to produce positive outcomes for those you lead.</p>
<p>The whole talk is embedded below &#8211;</p>
<p>[youtube http://youtu.be/e_5uhpN8aP8]</p>
</div>
<h3>Related Images:</h3>
<p> [<a href="https://thargy.com/2012/06/leadership/">See image gallery at thargy.com</a>] </p>
]]></content:encoded>
					
					<wfw:commentRss>https://thargy.com/2012/06/leadership/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">317</post-id>	</item>
		<item>
		<title>Breaking the cycle of training</title>
		<link>https://thargy.com/2012/06/breaking-the-cycle-of-training/</link>
					<comments>https://thargy.com/2012/06/breaking-the-cycle-of-training/#comments</comments>
		
		<dc:creator><![CDATA[thargy]]></dc:creator>
		<pubDate>Fri, 22 Jun 2012 12:40:26 +0000</pubDate>
				<category><![CDATA[Chamber of Commerce]]></category>
		<category><![CDATA[Management]]></category>
		<category><![CDATA[Centre of Excellence]]></category>
		<category><![CDATA[Developers]]></category>
		<category><![CDATA[Professionals]]></category>
		<category><![CDATA[Technologist]]></category>
		<category><![CDATA[Training]]></category>
		<guid isPermaLink="false">http://thargy.com/?p=315</guid>

					<description><![CDATA[This article first appeared as a guest blog on the GMCC Blog on 22 June 2012. I’m a technologist. I have an iPad and an iPhone, I have Android and Windows devices, I have an Xbox, a PS3, a Wii and even an AppleTV. It would be natural to think that I believe in technology ...]]></description>
										<content:encoded><![CDATA[<div class="entry">
<p>This article first appeared as a guest blog on the <a href="http://www.gmchamberblog.co.uk/2012/06/friday-guest-blog_22.html" target="_blank" rel="noopener noreferrer">GMCC Blog</a> on 22 June 2012.</p>
<p><a href="https://i0.wp.com/thargy.com/wp-content/uploads/2012/06/Craig-Head-Shot.png"><img data-recalc-dims="1" loading="lazy" decoding="async" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top: 0px; border-right: 0px; padding-top: 0px" title="Craig-Head-Shot" border="0" alt="Craig-Head-Shot" align="left" src="https://i0.wp.com/thargy.com/wp-content/uploads/2012/06/Craig-Head-Shot_thumb.png?resize=240%2C295" width="240" height="295"></a></p>
<p>I’m a technologist. I have an <a title="The new iPad" href="https://www.apple.com/uk/ipad/" target="_blank" rel="noopener noreferrer">iPad</a> and an iPhone, I have Android and Windows devices, I have an Xbox, a PS3, a Wii and even an AppleTV. It would be natural to think that I believe in technology as the solution to our woes. You would be very wrong. I believe in people. </p>
<p>When gadgets ‘do something clever’ it is because a genius told them to. Why worship the created when you can admire the creator? The only problem is that creators are distressingly in short supply. The reason for this is not a lack of desire or passion, according to the CRA the number of Computer Science graduates continues to rise. Young people still see I.T. as a rewarding career. The problem is our failure to inspire and develop the next generation to their true potential. Traditional training has flourished in industries which change little from year to year but it is wholly inappropriate for the world of I.T., where what you know today is out of date tomorrow. The concept of I.T. courses delivered by trainers is dated and unsuccessful, what developers are crying out for is I.T. courses delivered by developers not trainers. </p>
<p>Developers are too expensive to waste time on ineffective training, but something has to break the impasse. For that reason, we’re training our software engineers to train rather than trying to teach trainers to develop. It’s a revolutionary concept and requires some juggling, but it is vital to the future of our industry.</p>
<p>On the 29th June we’re opening the Centre of Excellence, an I.T. training facility where you won’t see any trainers. The professionals delivering the courses all work in industry – writing software all day – they’re taking a break to introduce you to an exciting new world. I hope you’ll join us.</p>
</div>
<h3>Related Images:</h3>
<p> [<a href="https://thargy.com/2012/06/breaking-the-cycle-of-training/">See image gallery at thargy.com</a>] </p>
]]></content:encoded>
					
					<wfw:commentRss>https://thargy.com/2012/06/breaking-the-cycle-of-training/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">315</post-id>	</item>
		<item>
		<title>The Metro is Open!</title>
		<link>https://thargy.com/2012/06/the-metro-is-open/</link>
					<comments>https://thargy.com/2012/06/the-metro-is-open/#comments</comments>
		
		<dc:creator><![CDATA[thargy]]></dc:creator>
		<pubDate>Sat, 16 Jun 2012 08:53:00 +0000</pubDate>
				<category><![CDATA[Chamber of Commerce]]></category>
		<category><![CDATA[Management]]></category>
		<category><![CDATA[Andy Crane]]></category>
		<category><![CDATA[BBC]]></category>
		<category><![CDATA[Change]]></category>
		<category><![CDATA[Comedy Store]]></category>
		<category><![CDATA[GMCC]]></category>
		<category><![CDATA[Interview]]></category>
		<category><![CDATA[Metrolink]]></category>
		<category><![CDATA[Mumps]]></category>
		<category><![CDATA[Oldham]]></category>
		<category><![CDATA[Radio]]></category>
		<guid isPermaLink="false">http://thargy.com/?p=306</guid>

					<description><![CDATA[Right, let me start by apologising for being a bit lax on the blogging front.  To be fair the Wi-Fi connection in Rhodes was a little underwhelming, and although I did pen an article it disappeared into the ether.  However, I’ve not been wasting my time off!  Thanks to everyone who left me so many ...]]></description>
										<content:encoded><![CDATA[<div class="entry">
<p>Right, let me start by apologising for being a bit lax on the blogging front.  To be fair the Wi-Fi connection in Rhodes was a little underwhelming, and although I did pen an article it disappeared into the ether.  However, I’ve not been wasting my time off!  Thanks to everyone who left me so many positive comments about <a title="Pressing the reset button on business" href="http://thargy.com/2012/05/pressing-the-reset-button-on-business/" target="_blank" rel="noopener noreferrer">my last article</a>, it was really encouraging to see so many people agreeing with the need for us to rethink the concept of shareholdings and I have a number of follow ups planned.</p>
<p>In the meantime, it has been a hugely exciting week here in Oldham.  For years we have talked about the <a href="https://tfgm.com:443/public-transport/tram" target="_blank" rel="noopener noreferrer">Metrolink</a> and it’s pending arrival.  There have been naysayers a plenty, but on Wednesday the first tram ran from Oldham mumps through Victoria station into the heart of Manchester, on a line that will eventually continue all the way to Manchester Airport!</p>
<p>Vivienne and I, joined a host of Webbies on Thursday evening at <a title="The Comedy Store" href="https://thecomedystore.co.uk/" target="_blank" rel="noopener noreferrer">The Comedy Store</a> for one of our many staff night’s out.  For the first time we decided to use the newly opened line and jumped on at the Freehold stop, a brisk 5 minute walk from home.  In just over half an hour we got off at the Deansgate stop, which sits (quite literally) atop <a title="The Comedy Store" href="https://thecomedystore.co.uk/" target="_blank" rel="noopener noreferrer">The Comedy Store</a>.  Oldham has officially arrived!</p>
<p>Levity aside, why does this matter?  I’ve been an avid supporter of <a href="https://tfgm.com:443/public-transport/tram" target="_blank" rel="noopener noreferrer">Metrolink</a> and its arrival in town.  As one of the larger land owners in the Mumps area, Web Applications has had every reason to join the ranks of bemoaners who have sniped continuously about the disruption, traffic issues and delays that have accompanied this huge infrastructure project.  There are few companies that can have been more effected by road closures.  Yet we chose to move to Mumps in 2009 believing (at a time many didn’t) that the <a href="https://tfgm.com:443/public-transport/tram" target="_blank" rel="noopener noreferrer">Metrolink</a> would indeed come, and being fully prepared for it’s impact.</p>
<p>We did so because we believe that change is necessary and, although painful, is vital to our town’s resurgence.  Too often it easy to criticise change, and in doing so it invariably discourages future investments.  Instead by having belief, by making do and being creative during the disruption (with flexible starting hours) we now stand to reap the benefits of improved transport links – right to our doorstep.</p>
<p>I genuinely put Web Applications&#8217; success to a willingness to not only accept change positively, but to a willingness to drive change.  In the modern economy it’s not about Change Control it’s about Change Driving.</p>
<p>Andy Crane interviewed me for BBC Radio Manchester just over a week ago about the opening &#8211;</p>
<p><iframe loading="lazy" class="youtube-player" width="480" height="270" src="https://www.youtube.com/embed/8DTHt-YhA2s?version=3&#038;rel=1&#038;showsearch=0&#038;showinfo=1&#038;iv_load_policy=1&#038;fs=1&#038;hl=en-GB&#038;autohide=2&#038;wmode=transparent" allowfullscreen="true" style="border:0;" sandbox="allow-scripts allow-same-origin allow-popups allow-presentation allow-popups-to-escape-sandbox"></iframe></p>
</div>
<h3>Related Images:</h3>
<p> [<a href="https://thargy.com/2012/06/the-metro-is-open/">See image gallery at thargy.com</a>] </p>
]]></content:encoded>
					
					<wfw:commentRss>https://thargy.com/2012/06/the-metro-is-open/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">306</post-id>	</item>
		<item>
		<title>Carmageddon: Reincarnation</title>
		<link>https://thargy.com/2012/05/carmageddon-reincarnation/</link>
		
		<dc:creator><![CDATA[thargy]]></dc:creator>
		<pubDate>Sat, 26 May 2012 10:00:20 +0000</pubDate>
				<category><![CDATA[Personal]]></category>
		<category><![CDATA[Carmageddon]]></category>
		<category><![CDATA[Kickstarter]]></category>
		<guid isPermaLink="false">http://thargy.com/?p=302</guid>

					<description><![CDATA[OK, call me nostalgic, but I loved this game back in the day, so I decided to become a kickstarter backer, I really hope this sees the light of day, only a little more money to raise! Related Images: [See image gallery at thargy.com]]]></description>
										<content:encoded><![CDATA[<div class="entry">
<p>OK, call me nostalgic, but I loved this game back in the day, so I decided to become a <a title="Kickstarter page for Carmageddon : Reincarnation" href="https://www.kickstarter.com/projects/stainlessgames/carmageddon-reincarnation" target="_blank">kickstarter backer</a>, I really hope this sees the light of day, only a little more money to raise!</p>
<p><iframe loading="lazy" width="480px" height="360px" frameborder="0" src="http://www.kickstarter.com/projects/stainlessgames/carmageddon-reincarnation/widget/video.html"></iframe><br />
<iframe loading="lazy" width="220px" height="380px" frameborder="0" src="http://www.kickstarter.com/projects/stainlessgames/carmageddon-reincarnation/widget/card.html"></iframe></p>
</div>
<h3>Related Images:</h3>
<p> [<a href="https://thargy.com/2012/05/carmageddon-reincarnation/">See image gallery at thargy.com</a>] </p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">302</post-id>	</item>
		<item>
		<title>Pressing the reset button on Business</title>
		<link>https://thargy.com/2012/05/pressing-the-reset-button-on-business/</link>
					<comments>https://thargy.com/2012/05/pressing-the-reset-button-on-business/#comments</comments>
		
		<dc:creator><![CDATA[thargy]]></dc:creator>
		<pubDate>Sat, 26 May 2012 08:28:19 +0000</pubDate>
				<category><![CDATA[Innovation]]></category>
		<category><![CDATA[Management]]></category>
		<category><![CDATA[ethics]]></category>
		<category><![CDATA[Frans de Waal]]></category>
		<category><![CDATA[Gordon Gecko]]></category>
		<category><![CDATA[Jack Welch]]></category>
		<category><![CDATA[Profit]]></category>
		<category><![CDATA[shareholder]]></category>
		<category><![CDATA[shareholder value]]></category>
		<category><![CDATA[shares]]></category>
		<category><![CDATA[Wall Street]]></category>
		<guid isPermaLink="false">http://thargy.com/?p=293</guid>

					<description><![CDATA[As I&#8217;ve mentioned before, I just don&#8217;t buy the fallacy that profit is the sole driving force of great businesses.  If you are a business owner (like I am), then it&#8217;s easy to understand why profit is such a motivation; profitable companies frequently equate to wealthy owners (though they don&#8217;t have to).  In my own case ...]]></description>
										<content:encoded><![CDATA[<div class="entry">
<p><figure id="attachment_296" aria-describedby="caption-attachment-296" style="width: 150px" class="wp-caption alignright"><a href="https://i0.wp.com/thargy.com/wp-content/uploads/2012/05/Michael-Douglas-File-5476447.jpg"><img data-recalc-dims="1" loading="lazy" decoding="async" class="size-thumbnail wp-image-296 " title="Michael-Douglas-File-5476447" src="https://i0.wp.com/thargy.com/wp-content/uploads/2012/05/Michael-Douglas-File-5476447-150x150.jpg?resize=150%2C150" alt="Gordon Gecko" width="150" height="150" srcset="https://i0.wp.com/thargy.com/wp-content/uploads/2012/05/Michael-Douglas-File-5476447.jpg?resize=150%2C150&amp;ssl=1 150w, https://i0.wp.com/thargy.com/wp-content/uploads/2012/05/Michael-Douglas-File-5476447.jpg?zoom=2&amp;resize=150%2C150&amp;ssl=1 300w" sizes="auto, (max-width: 150px) 100vw, 150px" /></a><figcaption id="caption-attachment-296" class="wp-caption-text">Michael Douglas as Gordon Gecko in Wall Street</figcaption></figure></p>
<p>As I&#8217;ve mentioned before, <a title="The measure of Success" href="http://thargy.com/2011/10/the-measure-of-success/">I just don&#8217;t buy the fallacy that profit is the sole driving force of great businesses</a>.  If you are a business owner (like I am), then it&#8217;s easy to understand <em>why</em> profit is such a motivation; profitable companies frequently equate to wealthy owners (though they don&#8217;t have to).  In my own case I (and my fellow owners) don&#8217;t rip the heart out of the business with huge dividends, instead we use profits to drive growth and reinvest in the business.</p>
<p>The concept of profit focused businesses is ultimately a selfish one.  A drive to profit at all costs devalues investment, growth, job creation and <a title="Corporate Social Responsibility" href="http://thargy.com/2012/02/corporate-social-responsibility/">CSR</a> for the sake of enrichment.  It&#8217;s also a view that ultimately derives from the common belief that people are inherently selfish.  I don&#8217;t buy that either, it&#8217;s a flawed projection of what Darwin was saying, rather than a substantive fact.  In my travels around the world I have spent time with literally thousands of people from numerous cultures, and I just can&#8217;t subscribe to such a view.  In my own experience, most of the people I meet are a complex mixture of selfish and <em>selfless</em> desires.</p>
<p><a title="Gordon Gecko - Wall Street" href="https://en.wikipedia.org/wiki/Gordon_Gecko" target="_blank" rel="noopener noreferrer">Gordon Gecko</a> got it wrong &#8211;</p>
<blockquote><p>&#8220;The point is, ladies and gentleman, that greed &#8211; for lack of a better word &#8211; is good.<br />
Greed works.<br />
Greed clarifies, cuts through, and captures the essence of the evolutionary spirit.<br />
Greed, in all of its forms &#8211; greed for life, for money, for love, knowledge &#8211; has marked the upward surge of mankind.<br />
And greed &#8211; you mark my words &#8211; will not only save Teldar Paper, but that other malfunctioning corporation called the USA.&#8221;</p></blockquote>
<p>In fact, in his book <em>&#8220;<a title="The Age of Empathy - available at Amazon." href="https://read.amazon.com/kp/embed?preview=newtab&amp;linkCode=kpe&amp;ref_=cm_sw_r_kb_dp_bQOvEb6HP3ZQ6&amp;asin=B006WB7KEA" target="_blank" rel="noopener noreferrer">The Age of Empathy: Nature&#8217;s Lessons for a Kinder Society </a>&#8220;</em>, <a title="Frans de Waal on Wikipedia" href="https://en.wikipedia.org/wiki/Frans_de_waal" target="_blank" rel="noopener noreferrer">Frans de Waal</a> (the dutch <a title="Primatologist" href="https://en.wikipedia.org/wiki/Primatologist">primatologist</a> and <a title="Ethologist" href="https://en.wikipedia.org/wiki/Ethologist">ethologist</a>) debunked the belief that humans are inherently selfish, demonstrating selfless traits in other species.  I particularly like the following quote &#8211;</p>
<blockquote><p>&#8220;The possibility that empathy resides in parts of the <a title="Brain" href="https://en.wikipedia.org/wiki/Brain">brain</a> so ancient that we share them with <a title="Rat" href="https://en.wikipedia.org/wiki/Rat">rats</a> should give pause to anyone comparing <a title="Politician" href="https://en.wikipedia.org/wiki/Politician">politicians</a> with those poor, underestimated creatures.&#8221;</p></blockquote>
<p>He also alludes to the admirable quality of empathy when he talks about my favourite subject (dogs) &#8211;</p>
<blockquote><p>&#8220;I&#8217;ve argued that many of what philosophers call moral sentiments can be seen in other species. In <a title="Chimpanzee" href="https://en.wikipedia.org/wiki/Chimpanzee">chimpanzees</a> and other animals, you see examples of sympathy, empathy, reciprocity, a willingness to follow social rules. <a title="Dog" href="https://en.wikipedia.org/wiki/Dog">Dogs</a> are a good example of a species that have and obey social rules; that&#8217;s why we like them so much, even though they&#8217;re large <a title="Carnivore" href="https://en.wikipedia.org/wiki/Carnivore">carnivores</a>.&#8221;</p></blockquote>
<p>If one can accept people can rise above selfishness, surely it is a small step to believe that business can too.  And if we admire animals for morality, and we clearly admire people for the same traits, then why do we not judge businesses &#8211; the ultimate endeavour of our collective efforts &#8211; in exactly the same way.  Surely the last measure of a business should be its level of self-interest?</p>
<p>Which is why we need to rethink public companies.  For too long the role of the collective &#8216;shareholder&#8217; has been an obsession over profitability.  I&#8217;m somewhat ambivalent to the <a title="Executive Pay consultation" href="https://assets.publishing.service.gov.uk/government/uploads/system/uploads/attachment_data/file/31372/12-639-executive-pay-shareholder-voting-rights-consultation.pdf" target="_blank" rel="noopener noreferrer">recent government consultation on executive pay</a>, which aims to hand yet more control to the shareholder masses.  On the one hand it helps prevent executives seeing businesses as a personal bank, to be leached for their own gain, on the other it reinforces the idea that the role of a shareholder is to stay out of the way unless it comes to issues regarding profitability.</p>
<p>Would that it were possible to come up with a concept where shareholders were rewarded based on their level of impact within an investment.  Shareholders, as a general collective, are focused purely on the return on their investment. I&#8217;m sure there are individual shareholders who would disagree &#8211; that take interest in the ethical impact of their investments, and indeed their are companies that offer ethical investment opportunities &#8211; but as a collective whole the evidence is pretty damning.</p>
<p><a title="Jack Welch" href="https://en.wikipedia.org/wiki/Jack_Welch">Jack Welch</a>, former CEO of <a title="General Electric" href="https://en.wikipedia.org/wiki/General_Electric">General Electric</a>, gave a speech that launched the concept of shareholder value.  <a title="Shareholder value" href="https://en.wikipedia.org/wiki/Shareholder_value" target="_blank" rel="noopener noreferrer">To quote wikipedia</a> &#8211;</p>
<blockquote><p>On August 12, 1981, <a title="Jack Welch" href="https://en.wikipedia.org/wiki/Jack_Welch">Jack Welch</a> made a speech at <a title="The Pierre" href="https://en.wikipedia.org/wiki/The_Pierre">The Pierre</a> in <a title="New York City" href="https://en.wikipedia.org/wiki/New_York_City">New York City</a> called <em>‘Growing fast in a slow-growth economy’</em>.<span style="font-size: 11px;"> </span> This is often acknowledged as the &#8220;dawn&#8221; of the obsession with shareholder value. Welch&#8217;s stated aim was to be the biggest or second biggest market player, and to return maximum value to stockholders.</p>
<p>In March 2009, Welch criticized parts of the application of this concept, calling a focus on shareholder quarterly profit and share price gains &#8220;the dumbest idea in the world&#8221;.  Welch then elaborated on this, claiming that the quotes were taken out of context.</p></blockquote>
<p>In reality, the legal premise of a publicly traded company is to maximise profits, in such a context public traded companies should not be deserving of our highest respect.</p>
<p>Does that mean I&#8217;m anti-profit?  Far from it!  In fact the danger of such polarising articles is that they can state one side of a coin too vehemently.  In reality profit is a necessity for thriving business, it is a key component of stability and growth.  In that context, profit is <em>vital</em>.  But it should never be the <em>sole measure</em> of a company any more than the ability to breathe is the true measure of a man.</p>
<p>We should aim higher, and we should look long and hard at how we judge companies.</p>
</div>
<h3>Related Images:</h3>
<p> [<a href="https://thargy.com/2012/05/pressing-the-reset-button-on-business/">See image gallery at thargy.com</a>] </p>
]]></content:encoded>
					
					<wfw:commentRss>https://thargy.com/2012/05/pressing-the-reset-button-on-business/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">293</post-id>	</item>
		<item>
		<title>Simulating SQL Server (Part 3)</title>
		<link>https://thargy.com/2012/05/simulating-sql-server-part-3/</link>
					<comments>https://thargy.com/2012/05/simulating-sql-server-part-3/#comments</comments>
		
		<dc:creator><![CDATA[thargy]]></dc:creator>
		<pubDate>Sun, 20 May 2012 13:04:13 +0000</pubDate>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Reflection]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[IDataReader]]></category>
		<category><![CDATA[IDataRecord]]></category>
		<category><![CDATA[Moq]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[TDD]]></category>
		<guid isPermaLink="false">http://thargy.com/?p=266</guid>

					<description><![CDATA[If you haven’t done so so already, start with &#8211; Simulating SQL Server (Part 1) Simulating SQL Server (Part 2) In the first two posts, I introduced the SqlTester library, which can be downloaded at the bottom of this post.  I also showed a series of classes that implemented IDataRecord and IDataReade to allow the creation ...]]></description>
										<content:encoded><![CDATA[<div class="entry">
<p>If you haven’t done so so already, start with &#8211;</p>
<p><a href="http://thargy.com/2012/05/simulating-sql-server-part-1/">Simulating SQL Server (Part 1)</a><br />
<a href="http://thargy.com/2012/05/simulating-sql-server-part-2/">Simulating SQL Server (Part 2)</a></p>
<p>In the first two posts, I introduced the SqlTester library, which can be downloaded at the bottom of this post.  I also showed a series of classes that implemented <a href="https://docs.microsoft.com/en-us/dotnet/api/system.data.idatarecord?redirectedfrom=MSDN&amp;view=netframework-4.8">IDataRecord</a> and <a href="https://docs.microsoft.com/en-us/dotnet/api/system.data.idatareader?redirectedfrom=MSDN&amp;view=netframework-4.8">IDataReade</a> to allow the creation of ‘fake’ database connections when testing code in unit tests.  For anyone who has tried messing around with compact databases (and the like) in their test projects, the resulting library can be a real time saver.</p>
<p>I also showed how the library could be used to quickly generate random data, using the same techniques first discussed in <a href="http://thargy.com/2012/04/generating-randomness/">Generating Randomness</a>.  That means we have the tools to create real test data and create lots of random data.  There is still one thing missing in our arsenal if we want to achieve a reasonable level of code coverage with our data layer tests.  We need to be able to simulate exceptions.</p>
<p>In <a href="http://thargy.com/2012/05/simulating-sql-server-part-1/">the first post</a> in the series, I introduced the <span class="lang:c# decode:true crayon-inline ">IObjectRecord</span> interface without comment, whilst introducing the <span class="lang:c# decode:true crayon-inline ">ObjectRecord</span>  class that implemented the interface.  It may have seemed strange that I placed an interface there, why not just use the class itself?  In <a href="http://thargy.com/2012/05/simulating-sql-server-part-2/">the second post</a>, I also introduced the <span class="lang:c# decode:true crayon-inline ">IObjectSet</span> , but this time, I showed two implementations – <span class="lang:c# decode:true crayon-inline ">ObjectSet</span>  and <span class="lang:c# decode:true crayon-inline ">RandomSet</span> .  The beauty of using the interfaces is it makes it easy to extend the base library yourself with further implementations.</p>
<p>It should come as no surprise then that I’ve included another implementation of <span class="lang:c# decode:true crayon-inline ">IObjectRecord</span>  as well – <span class="lang:c# decode:true crayon-inline ">ExceptionRecord</span> .  As the name suggests this record will throw an exception whenever it is accessed.  Unlike our other records, though, we don’t need to supply a record set definition.  Just like with a normal error we won’t be able to access any columns or data without this error being thrown anyway, so knowing the record set definition is irrelevant.</p>
<pre class="lang:csharp decode:1 mixed:false ">// Create an exception record (note it also implements IObjectRecord but does not require a record set definition
IObjectRecord exceptionRecord = new ExceptionRecord(new InvalidOperationException("Throw me throw a record set."));

// Add it to a new record set somewhere.
ObjectSet recordSet = new ObjectSet(recordSetDefinition)
{
    ...,
    exceptionRecord,
    ...
};
</pre>
<p>With this one class we can now ‘poison’ any record set, and make it fail exactly when we want to, and in the way we want to.</p>
<p>Of course, we still have a small problem here, what if we want to simulate an actual SQL Server error?  Perhaps your code (correctly) only intercepts exceptions descending from <a href="https://docs.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqlexception?redirectedfrom=MSDN&amp;view=netframework-4.8">SqlException</a>.  Unfortunately, there is no public constructor for creating a <a href="https://docs.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqlexception?redirectedfrom=MSDN&amp;view=netframework-4.8">SqlException</a>, after all, you shouldn’t normally be able to create one yourself as it’s reserved for errors coming from SQL.</p>
<p>Thankfully, using the power of <a href="http://thargy.com/category/dev/reflection/">reflection</a>, pretty much anything is possible, so I created some prototype classes to solve this particular conundrum for you easily.  As a technique you can use this for any such similar problem, but bare in mind people make classes private for a reason, so use with caution!</p>
<pre class="lang:csharp decode:1 mixed:false ">// To create a record that throws an exception we first create a SqlException
// We can't do this directly, but we can use our prototypes to construct one.

// SqlExceptions are made from a collection of SqlErrors - which can make like this :
SqlErrorCollection errorCollection = new SqlErrorCollectionPrototype
    {
        new SqlErrorPrototype(1000, 80, 17, "MyFakeServer",
         "Connection Timeout.", "spMySproc", 54)
    };

SqlException sqlException = new SqlExceptionPrototype(errorCollection, "9.0.0.0", Guid.NewGuid());
IObjectRecord exceptionRecord = new ExceptionRecord(sqlException);
</pre>
<p>So how do these work?</p>
<p>Well basically all three prototype classes (<span class="lang:c# decode:true crayon-inline ">SqlErrorPrototype</span> , <span class="lang:c# decode:true crayon-inline ">SqlErrorCollectionPrototype</span>  and <span class="lang:c# decode:true crayon-inline ">SqlExceptionPrototype</span> ) correspond to a framework class (<a href="https://docs.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqlerror?redirectedfrom=MSDN&amp;view=netframework-4.8">SqlError</a>, <a href="https://docs.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqlerrorcollection?redirectedfrom=MSDN&amp;view=netframework-4.8">SqlErrorCollection</a> and <a href="https://docs.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqlexception?redirectedfrom=MSDN&amp;view=netframework-4.8">SqlException</a> respectively).  And all three have implicit conversion operators defined to allow conversion between the prototype class and it’s corresponding framework class.  For example, <span class="lang:c# decode:true crayon-inline ">SqlErrorPrototype</span>  contains the following code &#8211;</p>
<pre class="lang:csharp decode:1 mixed:false mark:10 ">/// &lt;summary&gt;
/// Implicit conversion from &lt;see cref="SqlErrorPrototype"/&gt; to &lt;see cref="SqlError"/&gt;.
/// &lt;/summary&gt;
/// &lt;param name="prototype"&gt;The prototype.&lt;/param&gt;
/// &lt;returns&gt;The result of the operator.&lt;/returns&gt;
/// &lt;remarks&gt;&lt;/remarks&gt;
public static implicit operator SqlError(SqlErrorPrototype prototype)
{
    return prototype != null
               ? prototype.SqlError
               : null;
}

/// &lt;summary&gt;
/// Implicit conversion from &lt;see cref="SqlError" /&gt; to &lt;see cref="SqlErrorPrototype" /&gt;.
/// &lt;/summary&gt;
/// &lt;param name="sqlError"&gt;The SQL error.&lt;/param&gt;
/// &lt;returns&gt;The result of the operator.&lt;/returns&gt;
/// &lt;remarks&gt;&lt;/remarks&gt;
public static implicit operator SqlErrorPrototype(SqlError sqlError)
{
    return sqlError != null
               ? new SqlErrorPrototype(sqlError)
               : null;
}
</pre>
<p>Because we can implicitly convert to and from the prototype, the prototype can be used anywhere the real class is needed.</p>
<p>If you look at the methods above, you’ll also see a reference to a <span class="lang:c# decode:true crayon-inline ">public readonly</span>  field called <span class="lang:c# decode:true crayon-inline ">SqlError</span> .  This field is actually created the moment you create an instance of the object &#8211;</p>
<pre class="lang:csharp decode:1 mixed:false mark:19,20 ">/// &lt;summary&gt;
/// Initializes a new instance of the &lt;see cref="SqlErrorPrototype" /&gt; class, and in doing so initializes the &lt;see cref="SqlError" /&gt; property.
/// &lt;/summary&gt;
/// &lt;param name="infoNumber"&gt;The info number.&lt;/param&gt;
/// &lt;param name="errorState"&gt;State of the error.&lt;/param&gt;
/// &lt;param name="errorClass"&gt;The error class.&lt;/param&gt;
/// &lt;param name="server"&gt;The server.&lt;/param&gt;
/// &lt;param name="errorMessage"&gt;The error message.&lt;/param&gt;
/// &lt;param name="procedure"&gt;The procedure.&lt;/param&gt;
/// &lt;param name="lineNumber"&gt;The line number.&lt;/param&gt;
/// &lt;param name="win32ErrorCode"&gt;The win32 error code (if this error is the first in a &lt;see cref="SqlException"&gt;SqlException's&lt;/see&gt; collection then
/// this value will create an &lt;see cref="SqlException.InnerException"&gt;inner exception&lt;/see&gt; of type &lt;see cref="Win32Exception"/&gt;.&lt;/param&gt;
/// &lt;exception cref="System.ArgumentOutOfRangeException"&gt;&lt;/exception&gt;
/// &lt;remarks&gt;&lt;/remarks&gt;
public SqlErrorPrototype(int infoNumber, byte errorState, byte errorClass = 17,
                         string server = "Unspecified server", string errorMessage = "Unspecified error",
                         string procedure = "Unspecified procedure", int lineNumber = 0, uint win32ErrorCode = 0)
    : this(
        _constructor(infoNumber, errorState, errorClass, server, errorMessage, procedure, lineNumber,
                     win32ErrorCode))
{
}

/// &lt;summary&gt;
/// Initializes a new instance of the &lt;see cref="SqlErrorPrototype" /&gt; class.
/// &lt;/summary&gt;
/// &lt;param name="error"&gt;The error.&lt;/param&gt;
/// &lt;remarks&gt;&lt;/remarks&gt;
public SqlErrorPrototype([NotNull] SqlError error)
{
    Contract.Assert(error != null);
    SqlError = error;
}
</pre>
<p>Looking a the highlighted lines you can see that this calls an internal method (in fact it’s a <span class="lang:c# decode:true crayon-inline ">private static readonly</span>  field of type <span class="lang:c# decode:true crayon-inline ">Func&lt;…&gt;</span> ) that creates our actual <a href="https://docs.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqlerror?redirectedfrom=MSDN&amp;view=netframework-4.8">SqlError</a>.  So how is this magic function created?  Well, it’s created in a static constructor, and here comes a great example of <a href="http://thargy.com/2012/04/statics-and-generics/">where statics are useful</a>.  Because it’s in the static constructor it will be called once (and only once) whenever the class is first accessed – this is a cheap effective (and thread-safe) way to solve lazy initialisation.</p>
<pre class="lang:csharp decode:1 mixed:false ">/// &lt;summary&gt;
/// Creates the &lt;see cref="_constructor"/&gt; lambda.
/// &lt;/summary&gt;
/// &lt;remarks&gt;&lt;/remarks&gt;
static SqlErrorPrototype()
{
    // Find SqlError constructor.
    ConstructorInfo constructorInfo =
        typeof (SqlError).GetConstructor(
            BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.CreateInstance, null,
            new[]
                {
                    typeof (int),
                    typeof (byte),
                    typeof (byte),
                    typeof (string),
                    typeof (string),
                    typeof (string),
                    typeof (int),
                    typeof (uint)
                }, null);
    Contract.Assert(constructorInfo != null);

    // Create parameters
    List&lt;ParameterExpression&gt; parameters = new List&lt;ParameterExpression&gt;(4)
                                               {
                                                   Expression.Parameter(typeof (int), "infoNumber"),
                                                   Expression.Parameter(typeof (byte), "errorState"),
                                                   Expression.Parameter(typeof (byte), "errorClass"),
                                                   Expression.Parameter(typeof (string), "server"),
                                                   Expression.Parameter(typeof (string), "errorMessage"),
                                                   Expression.Parameter(typeof (string), "procedure"),
                                                   Expression.Parameter(typeof (int), "lineNumber"),
                                                   Expression.Parameter(typeof (uint), "win32ErrorCode")
                                               };

    // Create lambda expression.
    _constructor = Expression.Lambda&lt;Func&lt;int, byte, byte, string, string, string, int, uint, SqlError&gt;&gt;(
        Expression.New(constructorInfo, parameters), parameters).Compile();
}
</pre>
<p>Using the exact same techniques we create the other two prototype classes, which of course are in the code you can download.  I shall leave an explanation of how the code above works until a later post (when I introduce a generic function for creating <span class="lang:c# decode:true crayon-inline ">Action&lt;…&gt;</span> s and <span class="lang:c# decode:true crayon-inline ">Func&lt;…&gt;</span> s) but for now be assured that calling the resultant function is as quick as calling the constructor directly (and way quicker than the appalling <a href="https://docs.microsoft.com/en-us/dotnet/api/system.activator.createinstance?redirectedfrom=MSDN&amp;view=netframework-4.8">Activator.CreateInstance</a>).</p>
<p>Finally, the <span class="lang:c# decode:true crayon-inline ">ObjectReader</span>  has a few public methods that aren’t exposed via the <a href="https://docs.microsoft.com/en-us/dotnet/api/system.data.idatareader?redirectedfrom=MSDN&amp;view=netframework-4.8">IDataReader</a> interface (or the collection interface).  In the end, the <span class="lang:c# decode:true crayon-inline ">ObjectReader</span>  is a simple collection that keeps track of a single enumeration through it, unlike normal collections, where you can request multiple enumerators and enumerate them independently.  As any seasoned .NET developer will tell you, you can’t modify a collection <em>whilst</em> it is being enumerated.  So once you start using an <span class="lang:c# decode:true crayon-inline ">ObjectReader</span>  you can’t manipulate its contents.  To be accurate you can add/remove records to a record set other than the current one, but you can’t add/remove record sets.</p>
<p>To see where the <span class="lang:c# decode:true crayon-inline ">ObjectReader</span>  got up to you can use the <span class="lang:c# decode:true crayon-inline ">CurrentSet</span>  and <span class="lang:c# decode:true crayon-inline ">Current</span>  properties, which return the current set and the current record (which will be in the current set) respectively.</p>
<p>Unlike a real data reader, though, you can also use the <span class="lang:c# decode:true crayon-inline ">Reset</span>  method on <span class="lang:c# decode:true crayon-inline ">ObjectReader</span>  to reset the data reader back to the start (whilst keeping the data intact) so you can re-run a test (for example).</p>
<p>In the end, there’s a lot of functionality in the library and although I’ve covered some of the basics in these posts you can’t beat diving into the code and playing with it, so I recommend you <a href="https://github.com/thargy/SqlTester">view the code on GitHub</a> or use the download link below to see the complete project.  All I ask is that you leave a comment or feedback, and even some suggestions if you’d like improvements.  The code is free to use in open source or commercial projects, just acknowledge it’s source.</p>
<p>I hope you find a use in your own tests!</p>
<p><a href='https://thargy.com/download/sql-tester/?wpdmdl=710&refresh=6a0fd9a7dad161779423655'>        <div class="w3eden"><div class="link-btn light  pleft">    <div class="media">        <div class="pull-left wbt-left"><div class="wbt-icon">http://thargy.com/wp-content/plugins/download-manager/assets/file-type-icons/zip.png</div></div>        <div class="media-body text-left wbt-content"><strong class="ptitle">                SQL Tester            </strong>            <div style="font-size: 8pt;padding-top: 1px">Download <i style="margin: 4px 0 0 5px;opacity:0.5"                                                           class="fa fa-th-large"></i> 350.76 KB            </div>        </div>    </div></div><div style="clear: both;"></div></div><script>jQuery(function(){jQuery('.link-btn a.wpdm-download-link img').after('Download');jQuery('.link-btn a.wpdm-download-link img').remove();});</script></a></p>
</div>
<h3>Related Images:</h3>
<p> [<a href="https://thargy.com/2012/05/simulating-sql-server-part-3/">See image gallery at thargy.com</a>] </p>
]]></content:encoded>
					
					<wfw:commentRss>https://thargy.com/2012/05/simulating-sql-server-part-3/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">266</post-id>	</item>
		<item>
		<title>Simulating SQL Server (Part 2)</title>
		<link>https://thargy.com/2012/05/simulating-sql-server-part-2/</link>
					<comments>https://thargy.com/2012/05/simulating-sql-server-part-2/#comments</comments>
		
		<dc:creator><![CDATA[thargy]]></dc:creator>
		<pubDate>Fri, 18 May 2012 14:56:43 +0000</pubDate>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Reflection]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[IDataReader]]></category>
		<category><![CDATA[IDataRecord]]></category>
		<category><![CDATA[Moq]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[TDD]]></category>
		<guid isPermaLink="false">http://thargy.com/?p=224</guid>

					<description><![CDATA[If you haven’t read it already, why not start with Simulating SQL Server (Part 1)? Last time we looked at creating a RecordSetDefinition  as a collection of ColumnDefinition s.  Once we had a way of defining what a recordset looks like, we then were able to create an ObjectRecord . The next step is to collect those ...]]></description>
										<content:encoded><![CDATA[<div class="entry">
<p>If you haven’t read it already, why not start with <a href="http://thargy.com/2012/05/simulating-sql-server-part-1/">Simulating SQL Server (Part 1)</a>?</p>
<p>Last time we looked at creating a <span class="lang:c# decode:true crayon-inline ">RecordSetDefinition</span>  as a collection of <span class="lang:c# decode:true crayon-inline ">ColumnDefinition</span> s.  Once we had a way of defining what a recordset looks like, we then were able to create an <span class="lang:c# decode:true crayon-inline ">ObjectRecord</span> .</p>
<p>The next step is to collect those <span class="lang:c# decode:true crayon-inline ">ObectRecord</span> s together into a record set implementation.  For this I’ve added and <span class="lang:c# decode:true crayon-inline ">ObjectSet</span> .</p>
<p><a href="https://i0.wp.com/thargy.com/wp-content/uploads/2012/05/image7.png"><img data-recalc-dims="1" loading="lazy" decoding="async" style="background-image: none; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 0px; border: 0px;" title="image" src="https://i0.wp.com/thargy.com/wp-content/uploads/2012/05/image_thumb7.png?resize=640%2C299" alt="image" width="640" height="299" border="0" /></a></p>
<p>&nbsp;</p>
<p>Interestingly the <a href="https://en.wikipedia.org/wiki/Base_Class_Library">BCL</a> don’t expose a ‘recordset’ independently, instead, it’s always accessed through an <span class="lang:c# decode:true crayon-inline ">IDataReader</span> .  We want to be able to manipulate our recordsets though, so I added an <span class="lang:c# decode:true crayon-inline ">IObjectSet</span>  interface, and we can use the collection operators to make our sets, including <a href="https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/object-and-collection-initializers">Collection Initializers</a>.</p>
<pre class="lang:csharp decode:1 mixed:false ">// We can stick these records into a recordset
// Note the records must have the same RecordSetDefinition (unless it's an exception record)
// The final record will through an exception when reached!
ObjectSet recordSet = new ObjectSet(recordSetDefinition)
{
new ObjectRecord(recordSetDefinition, 1, "Test", "This is my test record"),
new ObjectRecord(recordSetDefinition, true)
};</pre>
<p>As we can create records independently of a record set (again great for testing a method that accepts an <a href="https://docs.microsoft.com/en-us/dotnet/api/system.data.idatarecord?redirectedfrom=MSDN&amp;view=netframework-4.8">IDataRecord</a>) then we need to be sure that any records we add to our record set implement the same <span class="lang:c# decode:true crayon-inline ">RecordSetDefinition</span> .  The above example adds two records, the second of which is random, of course, we can add and remove objects as we like &#8211;</p>
<pre class="lang:csharp decode:1 mixed:false">// Create a random record and add it.
IObjectRecord randomRecord = new ObjectRecord(recordSetDefinition, true);
recordSet.Add(randomRecord);

// And remove it again.
recordSet.Remove(randomRecord);</pre>
<p>But in many cases, we may not care about the actual data (or we want to test how well it copes with random data).  We already showed how to create a random record, so what we need is a fully random record set, and thankfully I added one of them too-</p>
<pre class="lang:csharp decode:1 mixed:false ">RandomSet randomSet = new RandomSet(recordSetDefinition);</pre>
<p>Couldn’t be easier – using the information from the <span class="lang:c# decode:true crayon-inline ">recordSetDefinition</span>  this creates between 0 and 1000 rows of random data.  There are lots of useful optional parameters here as well &#8211;</p>
<pre class="lang:csharp decode:1 mixed:false ">/// &lt;summary&gt;
/// Initializes a new instance of the &lt;see cref="RandomSet" /&gt; class.
/// &lt;/summary&gt;
/// &lt;param name="recordSetDefinition"&gt;The record set definition.&lt;/param&gt;
/// &lt;param name="minRows"&gt;The min rows.&lt;/param&gt;
/// &lt;param name="maxRows"&gt;The max rows.&lt;/param&gt;
/// &lt;param name="nullProbability"&gt;The probability of a column's value being set to SQL null (0.0 for no nulls) [Defaults to 0.1 = 10%].&lt;/param&gt;
/// &lt;param name="columnGenerators"&gt;The column generators is an array of functions that generate a value for each column, if the function is
/// &lt;see langword="null"/&gt; for a particular index then a random value is generated, if it is not null then the function is used. The function takes
/// the current row number as it's only parameter and must return an object of the correct type for the column.&lt;/param&gt;
/// &lt;exception cref="System.ArgumentOutOfRangeException"&gt;&lt;/exception&gt;
/// &lt;remarks&gt;&lt;/remarks&gt;
public RandomSet([NotNull] RecordSetDefinition recordSetDefinition, int minRows = 0, int maxRows = 1000,
double nullProbability = 0.1,
Func&lt;int, object&gt;[] columnGenerators = null)</pre>
<p>Which compares quite favourably to the full signature for creating a record &#8211;</p>
<pre class="lang:csharp decode:1 mixed:false ">/// &lt;summary&gt;
/// Initializes a new instance of the &lt;see cref="ObjectRecord" /&gt; class.
/// &lt;/summary&gt;
/// &lt;param name="recordSetDefinition"&gt;The table definition.&lt;/param&gt;
/// &lt;param name="randomData"&gt;if set to &lt;see langword="true" /&gt; fills columns with random data; otherwise fills them with their default values.&lt;/param&gt;
/// &lt;param name="nullProbability"&gt;The probability of a column's value being set to SQL null (0.0 for no nulls) -
/// this is only applicable is &lt;see paramref="randomData" /&gt; is set to &lt;see langword="true" /&gt; [Defaults to 0.1 = 10%].&lt;/param&gt;
/// &lt;param name="columnGenerators"&gt;The column generators is an array of functions that generate a value for each column, if the function is
/// &lt;see langword="null" /&gt; for a particular index then a random value is generated, if it is not null then the function is used. The function takes
/// the current row number as it's only parameter and must return an object of the correct type for the column.&lt;/param&gt;
/// &lt;param name="rowNumber"&gt;The optional row number to pass to the generator.&lt;/param&gt;
/// &lt;exception cref="System.ArgumentException"&gt;Thrown if the number of column generators exceeds the number of columns in the record set definition.&lt;/exception&gt;
/// &lt;remarks&gt;&lt;/remarks&gt;
public ObjectRecord([NotNull] RecordSetDefinition recordSetDefinition, bool randomData = false,
double nullProbability = 0.1,
Func&lt;int, object&gt;[] columnGenerators = null, int rowNumber = 1)</pre>
<p>Two useful parameters here include <span class="lang:c# decode:true crayon-inline ">nullProbability</span>  which determines how likely nulls will appear in columns (that are defined as allowing nulls) and <span class="lang:c# decode:true crayon-inline ">columnGenerators</span>  which allow a function to optionally be specified for columns that you want to generate specific values for (e.g. lookup out of an array). An example is shown below.</p>
<p>Now we have a recordset, it’s only used in an <span class="lang:c# decode:true crayon-inline">IDataReader</span> , so for this, we create another Collection, <span class="lang:c# decode:true crayon-inline">ObjectReader</span>  which implements <span class="lang:c# decode:true crayon-inline">IDataReader</span>  as well as <span class="lang:c# decode:true crayon-inline ">ICollection&lt;IObjectSet&gt;</span> . Again we can use <a href="https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/object-and-collection-initializers">Collection Initializers</a> &#8211;</p>
<pre class="lang:csharp decode:1 mixed:false ">// We can add recordsets to an ObjectReader
ObjectReader reader = new ObjectReader
{
recordSet
};</pre>
<p>We now have a reader with one record set in it but more, can be added, e.g. a random set &#8211;</p>
<pre class="lang:csharp decode:1 mixed:false ">// We can also fix certain rows values using the column generators arry, a null indicates
// that the column should us a random value, otherwise a lambda can be supplied - in this case
// it sets the row to the row number (1 - indexed).
reader.Add(new RandomSet(recordSetDefinition,
columnGenerators: new Func&lt;int, object&gt;[] {null, row =&gt; "Row #" + row}));</pre>
<p>And finally, we can use this reader just like a normal data reader &#8211;</p>
<pre class="lang:csharp decode:1 mixed:false ">// Now that we have a reader we can use it like a normal reader - it even simulates disposal.
using (IDataReader dataReader = reader)
{
int recordset = 1;
do
{
Trace.Write("Recordset #" + recordset);
int rows = 0;
while (dataReader.Read())
rows++;
Trace.WriteLine(" - " + rows + " rows.");
recordset++;
} while (dataReader.NextResult());
}</pre>
<p>Again the full project can be <a href="https://github.com/thargy/SqlTester">viewed on GitHub</a> or use the download link below to see the complete project.  <a title="Simulating SQL Server (Part 3)" href="http://thargy.com/2012/05/simulating-sql-server-part-3/">Next time</a> we will look in more detail at the other functions of the ObjectReader, and also we&#8217;ll attempt to simulate realistic SQL Server errors.</p>
<p><a href='https://thargy.com/download/sql-tester/?wpdmdl=710&refresh=6a0fd9a7dcbd51779423655'>        <div class="w3eden"><div class="link-btn light  pleft">    <div class="media">        <div class="pull-left wbt-left"><div class="wbt-icon">http://thargy.com/wp-content/plugins/download-manager/assets/file-type-icons/zip.png</div></div>        <div class="media-body text-left wbt-content"><strong class="ptitle">                SQL Tester            </strong>            <div style="font-size: 8pt;padding-top: 1px">Download <i style="margin: 4px 0 0 5px;opacity:0.5"                                                           class="fa fa-th-large"></i> 350.76 KB            </div>        </div>    </div></div><div style="clear: both;"></div></div><script>jQuery(function(){jQuery('.link-btn a.wpdm-download-link img').after('Download');jQuery('.link-btn a.wpdm-download-link img').remove();});</script></a></p>
</div>
<h3>Related Images:</h3>
<p> [<a href="https://thargy.com/2012/05/simulating-sql-server-part-2/">See image gallery at thargy.com</a>] </p>
]]></content:encoded>
					
					<wfw:commentRss>https://thargy.com/2012/05/simulating-sql-server-part-2/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">224</post-id>	</item>
		<item>
		<title>Assembly versioning</title>
		<link>https://thargy.com/2012/05/assembly-versioning/</link>
		
		<dc:creator><![CDATA[thargy]]></dc:creator>
		<pubDate>Tue, 08 May 2012 08:17:14 +0000</pubDate>
				<category><![CDATA[Personal]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[Assembly]]></category>
		<category><![CDATA[Attribute]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[DateTime]]></category>
		<category><![CDATA[Executable]]></category>
		<category><![CDATA[Properties]]></category>
		<guid isPermaLink="false">http://thargy.com/?p=210</guid>

					<description><![CDATA[Ever since the release of .NET 1.1, there has existed an AssemblyVersionAttribute.  This attribute determines the version number boiled into all .NET assemblies that is (supposed to) indicate something about when the assembly was built. Whenever you create a new C# project in Visual Studio, it helpfully creates an “AssemblyInfo.cs” file (found in the project’s ...]]></description>
										<content:encoded><![CDATA[<div class="entry">
<p>Ever since the release of .NET 1.1, there has existed an <a href="https://docs.microsoft.com/en-us/dotnet/api/system.reflection.assemblyversionattribute?redirectedfrom=MSDN&amp;view=netframework-4.8">AssemblyVersionAttribute</a>.  This attribute determines the version number boiled into all .NET assemblies that is (supposed to) indicate something about when the assembly was built.</p>
<p>Whenever you create a new <a href="https://en.wikipedia.org/wiki/C_Sharp_(programming_language)">C#</a> project in <a href="https://visualstudio.microsoft.com/">Visual Studio</a>, it helpfully creates an “AssemblyInfo.cs” file (found in the project’s ‘Properties’ subfolder), that the new developer generally ignores (to their cost).  This file is mostly auto-generated and manipulated from the project’s property pane.</p>
<p><a href="https://i0.wp.com/thargy.com/wp-content/uploads/2012/05/image1.png"><img data-recalc-dims="1" loading="lazy" decoding="async" style="background-image: none; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 0px; border-width: 0px;" title="image" src="https://i0.wp.com/thargy.com/wp-content/uploads/2012/05/image_thumb1.png?resize=644%2C426" alt="image" width="644" height="426" border="0" /></a></p>
<p>For example, the above property pane from a blank console application leads to the following “AssemblyInfo.cs” file:</p>
<pre class="lang: csharp mixed:false decode:true">using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("ConsoleApplication1")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ConsoleApplication1")]
[assembly: AssemblyCopyright("Copyright ©  2012")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components.  If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("4891b4c5-8e51-495b-ad47-1cb2f5a4e20e")]

// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version
//      Build Number
//      Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]</pre>
<p>Unfortunately, the usefulness of the property pane means too many developers never get round to looking at this bit of code, or the helpful comments, which is why <a href="https://visualstudio.microsoft.com/">Visual Studio</a> hides it away in the “Properties” subfolder in the first place.</p>
<p>The first thing to note is the funny syntax <span class="lang:c# decode:true crayon-inline ">[assembly: AssemblyVersion(&#8220;1.0.0.0&#8221;)]</span> .  Actually, if you take a look at the <a href="https://docs.microsoft.com/en-us/previous-versions/z0w1kczw(v=vs.140)?redirectedfrom=MSDN">MSDN attributes documentation</a>, you will see that this is the full syntax for declaring an attribute – the bit before the <span class="lang:c# decode:true crayon-inline ">:</span>  is actually the attribute target being set explicitly rather than being implied.  This is particularly useful for assembly attributes – where there’s no code element to stick them next to.  Actually, from the same documentation, you’ll notice some of the other elements that can be targeted with an attribute – but that’s another story that I might come back to in a later post.</p>
<p>So these are just normal attributes, targeted at an assembly itself.  And there’s quite a few of them.  As you can see from the above screenshot, it’s possible to edit them all using the “Assembly <span style="text-decoration: underline;">I</span>nformation…” link on the first pane of the project’s properties panel.  However, if you take the time to read the helpful comments in the source you can find some really useful information, and (importantly) you learn about the “1.0.*” assembly version trick.</p>
<p>When you specify version as “1.0.*” it get’s set automatically at build time to a new value which is based on the date and time of the build – which is exactly what we want!  So what we need to do here is to change the last <em>two</em> lines to &#8211;</p>
<pre class="lang: csharp mixed:false decode:true">[assembly: AssemblyVersion("1.0.*")]</pre>
<p>If you drop the <span class="lang:c# decode:true crayon-inline ">AssemblyFileVersion</span>  attribute then the file version is set to being, the same as the assembly version (which is what you want in the majority of cases).</p>
<p>At this point, if you’re getting confused by <span class="lang:c# decode:true crayon-inline ">AssemblyVersion</span>  in the code, but <span class="lang:c# decode:true crayon-inline ">AssemblyVersionAttribute</span>  in the documentation, then don’t worry you can use either as the attribute name, but by convention (and for convenience) <a href="https://en.wikipedia.org/wiki/C_Sharp_(programming_language)">C#</a> lets you drop the “Attribute” suffix from the attribute class name.</p>
<p>So what happens if we build our console application – well we get a nice executable file and if we browse to it and open up the file’s properties pane we can see the following on the details tab:</p>
<p><a href="https://i0.wp.com/thargy.com/wp-content/uploads/2012/05/image2.png"><img data-recalc-dims="1" loading="lazy" decoding="async" style="background-image: none; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 0px; border: 0px;" title="image" src="https://i0.wp.com/thargy.com/wp-content/uploads/2012/05/image_thumb2.png?resize=428%2C484" alt="image" width="428" height="484" border="0" /></a></p>
<p>As you can see the File version and Product version (which is our “AssemblyVersion”) are both set to “1.0.4511.14207” and if we built it again – it changes:</p>
<p><a href="https://i0.wp.com/thargy.com/wp-content/uploads/2012/05/image3.png"><img data-recalc-dims="1" loading="lazy" decoding="async" style="background-image: none; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 0px; border: 0px;" title="image" src="https://i0.wp.com/thargy.com/wp-content/uploads/2012/05/image_thumb3.png?resize=354%2C484" alt="image" width="354" height="484" border="0" /></a></p>
<p>Now it’s set to “1.0.4511.14<span style="text-decoration: underline;">356</span>”.  So clearly, this is a different version of the application.  It’s probably worth pausing and pointing to the other useful information in the properties window, which also comes from the assembly attributes.  If nothing else you now know why it’s worth spending the time setting all those values!  (Though in the example above they’re all defaulted).</p>
<p>But what about those numbers, let’s be honest they’re hardly very useful, apart from indicating which build was newer (14356 is more than 14207).  Well, in fact, going back to our friend <a href="https://docs.microsoft.com/en-us/">MSDN</a>, we discover that <a href="https://docs.microsoft.com/en-us/dotnet/api/system.reflection.assemblyversionattribute?redirectedfrom=MSDN&amp;view=netframework-4.8">version 3 of the documentation for AssemblyVersionAttribute</a> has the following useful nugget of information:</p>
<p>“When specifying a version, you have to at least specify <strong>major</strong>. If you specify <strong>major</strong> and <strong>minor</strong>, you can specify an asterisk (*) for the <strong>build</strong>. This will cause the <strong>build</strong> to be equal to the number of days since January 1, 2000, local time, and for <strong>revision</strong> to be equal to the number of seconds since midnight local time, divided by 2.”</p>
<p>So the “4511” in our example is the number of days since 1 January 2000, and the “14356” is the number of seconds since midnight, divided by 2.  Great, has anyone got a calculator?  Funny you should mention that &#8211;</p>
<p><a href="https://i0.wp.com/thargy.com/wp-content/uploads/2012/05/image4.png"><img data-recalc-dims="1" loading="lazy" decoding="async" style="background-image: none; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 0px; border: 0px;" title="image" src="https://i0.wp.com/thargy.com/wp-content/uploads/2012/05/image_thumb4.png?resize=700%2C122" alt="image" width="700" height="122" border="0" /></a></p>
<p>&nbsp;</p>
<p>After a lot of internal debate about using things like revision numbers from source control systems (which we did for a while) or using invalid version numbers like 1.0.20110508.75832 (each element is supposed to be a 32-bit integer), I threw together the above little utility to allow easy conversion between the default version number and the actual date and time.  So from our original example, you can see the date was today (8 May 2012) and the time was 7:53AM (notice the last updated was 8:53AM because of daylight saving)</p>
<p><a href="https://i0.wp.com/thargy.com/wp-content/uploads/2012/05/image5.png"><img data-recalc-dims="1" loading="lazy" decoding="async" style="background-image: none; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 0px; border: 0px;" title="image" src="https://i0.wp.com/thargy.com/wp-content/uploads/2012/05/image_thumb5.png?resize=700%2C122" alt="image" width="700" height="122" border="0" /></a></p>
<p>The second build was 5 minutes later.</p>
<p>So we can now get really useful information from builds – in fact, you can also drag assemblies straight onto the tool &#8211;</p>
<p><a href="https://i0.wp.com/thargy.com/wp-content/uploads/2012/05/image6.png"><img data-recalc-dims="1" loading="lazy" decoding="async" style="background-image: none; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 0px; border: 0px;" title="image" src="https://i0.wp.com/thargy.com/wp-content/uploads/2012/05/image_thumb6.png?resize=640%2C129" alt="image" width="640" height="129" border="0" /></a></p>
<p>In the example above, you can see the debug and release assemblies were built at different times.</p>
<p>The other buttons allow useful stuff like auto-generation (to show the current date &amp; time in version format) and copy to clipboard.</p>
<p>This tool is ‘commentware’ that is use it as much as you want but please leave me a comment <img data-recalc-dims="1" decoding="async" class="wlEmoticon wlEmoticon-smile" style="border-style: none;" src="https://i0.wp.com/thargy.com/wp-content/uploads/2012/05/wlEmoticon-smile.png" alt="Smile" />!</p>
<p><a href='https://thargy.com/download/version-calculator/?wpdmdl=717&refresh=6a0fd9a7df3891779423655'>        <div class="w3eden"><div class="link-btn light  pleft">    <div class="media">        <div class="pull-left wbt-left"><div class="wbt-icon">http://thargy.com/wp-content/plugins/download-manager/assets/file-type-icons/_blank.png</div></div>        <div class="media-body text-left wbt-content"><strong class="ptitle">                Version Calculator            </strong>            <div style="font-size: 8pt;padding-top: 1px">Download <i style="margin: 4px 0 0 5px;opacity:0.5"                                                           class="fa fa-th-large"></i> 1.54 MB            </div>        </div>    </div></div><div style="clear: both;"></div></div><script>jQuery(function(){jQuery('.link-btn a.wpdm-download-link img').after('Download');jQuery('.link-btn a.wpdm-download-link img').remove();});</script></a></p>
</div>
<h3>Related Images:</h3>
<p> [<a href="https://thargy.com/2012/05/assembly-versioning/">See image gallery at thargy.com</a>] </p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">210</post-id>	</item>
		<item>
		<title>Simulating SQL Server (Part 1)</title>
		<link>https://thargy.com/2012/05/simulating-sql-server-part-1/</link>
					<comments>https://thargy.com/2012/05/simulating-sql-server-part-1/#comments</comments>
		
		<dc:creator><![CDATA[thargy]]></dc:creator>
		<pubDate>Sat, 05 May 2012 16:14:44 +0000</pubDate>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Reflection]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[IDataReader]]></category>
		<category><![CDATA[IDataRecord]]></category>
		<category><![CDATA[Moq]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[TDD]]></category>
		<category><![CDATA[Type]]></category>
		<guid isPermaLink="false">http://thargy.com/?p=185</guid>

					<description><![CDATA[In my last post, I talked about creating random values for all kinds of interesting types.  One of the biggest complaints I get when encouraging developers to implement unit tests (or dare I say even start thinking about TDD as a development methodology) is that testing code that accesses databases is a huge pain.  For ...]]></description>
										<content:encoded><![CDATA[<div class="entry">
<p>In my last post, I talked about <a href="http://thargy.com/2012/04/generating-randomness/">creating random values for all kinds of interesting types</a>.  One of the biggest complaints I get when encouraging developers to implement unit tests (or dare I say even start thinking about <a href="https://en.wikipedia.org/wiki/Test-driven_development">TDD</a> as a development methodology) is that testing code that accesses databases is a huge pain.  For this reason, most code is written to use a data layer which is accessed by easily <a href="https://code.google.com/archive/p/moq">mockable</a> interfaces.</p>
<p>But what of the data layer itself?  Well too often it goes untested, occasionally some brave developer might introduce a ‘test database’ into the solution, or even a ‘test script’ for building a test database.  But that takes time, it’s a pain and nine times out of ten it’s overkill.</p>
<p><a href="https://i0.wp.com/thargy.com/wp-content/uploads/2012/05/image.png"><img data-recalc-dims="1" loading="lazy" decoding="async" style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; float: right; padding-top: 0px; border-width: 0px;" title="image" src="https://i0.wp.com/thargy.com/wp-content/uploads/2012/05/image_thumb.png?resize=136%2C240" alt="image" width="136" height="240" align="right" border="0" /></a>As an alternative, I decided to create a really simple set of classes that implement <a href="https://docs.microsoft.com/en-us/dotnet/api/system.data.idatareader?redirectedfrom=MSDN&amp;view=netframework-4.8">IDataReader</a> and <a href="https://docs.microsoft.com/en-us/dotnet/api/system.data.idatarecord?redirectedfrom=MSDN&amp;view=netframework-4.8">IDataRecord</a>, and (as much as possible) allow simulation of a SQL Server connection.  The goal was to allow unit tests to be created quickly and (most importantly) consistently without requiring a separate database.</p>
<p>The first step to achieving this aim was to be able to define what a recordset looks like.  All this information is required by the above interfaces, so it was a good starting place.  To do this I started by looking in the <a href="https://docs.microsoft.com/en-us/dotnet/api/system.data.sqlclient?redirectedfrom=MSDN&amp;view=netframework-4.8">System.Data.SqlClient</a> namespace which is defined in the <a href="https://docs.microsoft.com/en-us/previous-versions/gg145028(v=vs.110)?redirectedfrom=MSDN">System.Data</a> assembly.  Using <a href="http://thargy.com/category/dev/reflection/">reflection</a> I quickly found the internal <span class="lang:c# decode:true crayon-inline ">MetaType</span>  class, which handily defines all the known types supported by SQL Server.</p>
<p>From the information gleaned from <a href="http://thargy.com/category/dev/reflection/">reflection</a>, I could create my own class that given a <a href="https://docs.microsoft.com/en-us/dotnet/api/system.data.sqldbtype?redirectedfrom=MSDN&amp;view=netframework-4.8">SqlDbType</a> (or even a <a href="https://docs.microsoft.com/en-us/dotnet/api/system.data.dbtype?redirectedfrom=MSDN&amp;view=netframework-4.8">DbType</a>) could fill in all the other useful information for you automatically, using an ugly (but highly effective) large switch statement.</p>
<p>In most cases the type is enough, however for more complex types, more complex information is needed.  The constructor accepts a number of optional parameters:</p>
<pre class="lang:csharp decode:true mixed:false">/// &lt;summary&gt;
/// Initializes a new instance of the &lt;see cref="ColumnDefinition" /&gt; class.
/// &lt;/summary&gt;
/// &lt;param name="name"&gt;The name.&lt;/param&gt;
/// &lt;param name="sqlDbType"&gt;The columns type.&lt;/param&gt;
/// &lt;param name="length"&gt;The length (if fixed length).&lt;/param&gt;
/// &lt;param name="fill"&gt;if set to &lt;see langword="true" /&gt; expects the column to be full (only appropriate for fixed length columns).&lt;/param&gt;
/// &lt;param name="isNullable"&gt;if set to &lt;see langword="true" /&gt; the column is nullable.&lt;/param&gt;
/// &lt;param name="defaultValue"&gt;The default value (required if column is not nullable).&lt;/param&gt;
/// &lt;exception cref="System.ArgumentOutOfRangeException"&gt;Thrown if the &lt;see paramref="sqlDbType"/&gt; is unsupported.&lt;/exception&gt;
/// &lt;exception cref="System.ArgumentOutOfRangeException"&gt;Thrown if the &lt;see paramref="defaultValue"/&gt; is invalid for the specified &lt;see paramref="sqlDbType"/&gt;.&lt;/exception&gt;
/// &lt;remarks&gt;&lt;/remarks&gt;
public ColumnDefinition([NotNull] string name, SqlDbType sqlDbType, int length = -1, bool fill = false,
                        bool isNullable = true, object defaultValue = null)
{
    ...
}</pre>
<p>The <span class="lang:c# decode:true crayon-inline ">fill</span>  parameter helps indicate whether any values used fill the length (e.g. for fixed length types like char) or whether the length indicates a maximum (e.g. for varchar).  The <span class="lang:c# decode:true crayon-inline ">isNullable</span>  parameter is self-explanatory, but it is notable that the <span class="lang:c# decode:true crayon-inline ">defaultValue</span>  must always be supplied if <span class="lang:c# decode:true crayon-inline ">isNullable</span>  is false.</p>
<p>One we have column definitions we use them to define a recordset, this is done with our <span class="lang:c# decode:true crayon-inline ">RecordSetDefinition</span>  class, which accepts an enumeration of <span class="lang:c# decode:true crayon-inline ">ColumnDefinition</span>  objects in its constructor.  For example:</p>
<pre class="lang:csharp mixed:false decode:true">// To create a record that implement IDataRecord we start with a record set definition.
RecordSetDefinition recordSetDefinition = new RecordSetDefinition(
    new ColumnDefinition("ID", SqlDbType.Int),
    new ColumnDefinition("Name", SqlDbType.Char, 50),
    new ColumnDefinition("Description", SqlDbType.NVarChar),
    // This column is not nullable so defaults to true
    new ColumnDefinition("Active", SqlDbType.Bit, isNullable: false, defaultValue: true)
    );</pre>
<p>This immediately meets our goal of providing a clean intuitive syntax for quickly defining a table (or recordset) to be used by our reader.</p>
<p>Once we have a definition for a recordset we can create records.  The easiest way is with the <span class="lang:c# decode:true crayon-inline ">ObjectRecord</span>  class.</p>
<pre class="lang:csharp decode:true mixed:false">IObjectRecord dataRecord = new ObjectRecord(recordSetDefinition, 1, "Test", "This is my test record");</pre>
<p>The constructor used accepts a <span class="lang:c# decode:true crayon-inline ">RecordSetDefinition</span>  and a set of values (of type <span class="lang:c# decode:true crayon-inline ">object</span> ) which are validated against the definition.  Any missing values (in the above example the ‘Active’ column is not supplied) are set to their defaults as defined by the <span class="lang:c# decode:true crayon-inline ">RecordSetDefinition</span> .</p>
<p>If we don’t want to explicitly set the values, and we want more than their defaults, we can use the other constructor &#8211;</p>
<pre class="lang:csharp mixed:false decode:true">/// &lt;summary&gt;
/// Initializes a new instance of the &lt;see cref="ObjectRecord" /&gt; class.
/// &lt;/summary&gt;
/// &lt;param name="recordSetDefinition"&gt;The table definition.&lt;/param&gt;
/// &lt;param name="randomData"&gt;if set to &lt;see langword="true" /&gt; fills columns with random data; otherwise fills them with their default values.&lt;/param&gt;
/// &lt;param name="nullProbability"&gt;The probability of a column's value being set to SQL null (0.0 for no nulls) -
/// this is only applicable is &lt;see cref="randomData" /&gt; is set to &lt;see langword="true" /&gt; [Defaults to 0.1 = 10%].&lt;/param&gt;
/// &lt;param name="columnGenerators"&gt;The column generators is an array of functions that generate a value for each column, if the function is
/// &lt;see langword="null" /&gt; for a particular index then a random value is generated, if it is not null then the function is used.  The function takes
/// the current row number as it's only parameter and must return an object of the correct type for the column.&lt;/param&gt;
/// &lt;param name="rowNumber"&gt;The optional row number to pass to the generator.&lt;/param&gt;
/// &lt;exception cref="System.ArgumentException"&gt;Thrown if the number of column generators exceeds the number of columns in the record set definition.&lt;/exception&gt;
/// &lt;remarks&gt;&lt;/remarks&gt;
public ObjectRecord([NotNull] RecordSetDefinition recordSetDefinition, bool randomData = false,
                    double nullProbability = 0.1,
                    Func&lt;int, object&gt;[] columnGenerators = null, int rowNumber = 1)
{
    ...
}</pre>
<p>which will randomly fill in the columns with valid values, using the code we wrote in <a href="http://thargy.com/2012/04/generating-randomness/">Generating Randomness</a>.  For example &#8211;</p>
<pre class="lang:csharp mixed:false decode:true">IObjectRecord randomRecord = new ObjectRecord(recordSetDefinition, true);</pre>
<p>With these two classes, we can create an object that faithfully implements <a href="https://docs.microsoft.com/en-us/dotnet/api/system.data.idatarecord?redirectedfrom=MSDN&amp;view=netframework-4.8">IDataRecord</a>, without installing a database into our test project.</p>
<p><a title="Simulating SQL Server (Part 2)" href="http://thargy.com/2012/05/simulating-sql-server-part-2/">Next time</a> we will look at creating a record set and a data reader, but in the meantime, you can <a href="https://github.com/thargy/SqlTester">view the code on GitHub</a> or use the download link below to see the complete project.</p>
<p><a href='https://thargy.com/download/sql-tester/?wpdmdl=710&refresh=6a0fd9a7e19891779423655'>        <div class="w3eden"><div class="link-btn light  pleft">    <div class="media">        <div class="pull-left wbt-left"><div class="wbt-icon">http://thargy.com/wp-content/plugins/download-manager/assets/file-type-icons/zip.png</div></div>        <div class="media-body text-left wbt-content"><strong class="ptitle">                SQL Tester            </strong>            <div style="font-size: 8pt;padding-top: 1px">Download <i style="margin: 4px 0 0 5px;opacity:0.5"                                                           class="fa fa-th-large"></i> 350.76 KB            </div>        </div>    </div></div><div style="clear: both;"></div></div><script>jQuery(function(){jQuery('.link-btn a.wpdm-download-link img').after('Download');jQuery('.link-btn a.wpdm-download-link img').remove();});</script></a></p>
</div>
<h3>Related Images:</h3>
<p> [<a href="https://thargy.com/2012/05/simulating-sql-server-part-1/">See image gallery at thargy.com</a>] </p>
]]></content:encoded>
					
					<wfw:commentRss>https://thargy.com/2012/05/simulating-sql-server-part-1/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">185</post-id>	</item>
		<item>
		<title>Generating Randomness</title>
		<link>https://thargy.com/2012/04/generating-randomness/</link>
					<comments>https://thargy.com/2012/04/generating-randomness/#comments</comments>
		
		<dc:creator><![CDATA[thargy]]></dc:creator>
		<pubDate>Sun, 29 Apr 2012 19:27:59 +0000</pubDate>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Extension Method]]></category>
		<category><![CDATA[Random]]></category>
		<guid isPermaLink="false">http://thargy.com/?p=168</guid>

					<description><![CDATA[My new year’s resolution for this year was to not only start blogging more frequently but also to Open Source some of our core libraries that I’ve worked on over the years. In preparation for that though it’s important I cover some of the basics and explain the reasoning behind some of the code we’ll ...]]></description>
										<content:encoded><![CDATA[<div class="entry">
<p>My new year’s resolution for this year was to not only start blogging more frequently but also to Open Source some of our core libraries that I’ve worked on over the years. In preparation for that though it’s important I cover some of the basics and explain the reasoning behind some of the code we’ll be putting out there.</p>
<p>I thought we’d start with something pretty easy, but hopefully with enough twist to interest more advanced readers. Today I’m starting with random number generation – or more precisely random stuff generation. This will form part of some future test code, but for now, I’d like to look at this small subset of the overall problem.</p>
<p>The first thing about the random generation in .NET is the <a href="https://docs.microsoft.com/en-us/dotnet/api/system.random?redirectedfrom=MSDN&amp;view=netframework-4.8">System.Random</a> class. Now, I’m assuming you’re mostly familiar with this little gem, but if not, here are some quick examples &#8211;</p>
<pre class="lang:c# decode:true mixed:false">// Create a random number generator
Random random = new Random();

// Generate a random number between 0 and Int.MaxValue-1 inclusive.
int a = random.Next();
// Generate a random number between 0 and 49 inclusive.
int b = random.Next(50);
// Generate a random number between 10 and 49 inclusive.
int c = random.Next(10, 50);

// Generate a random double between 0.0 inclusive and 1.0 exclusive
double d = random.NextDouble();

// Fill a buffer with random bytes (each byte having every possible value).
byte[] buffer = new byte[10];
random.NextBytes(buffer);</pre>
<p>The important (and often missed) point of these examples is that the upper bound of the <span class="lang:c# decode:true crayon-inline ">Next</span> overloads is <em>exclusive</em>, that is it’s impossible to get <span class="lang:c# decode:true crayon-inline ">Int32.MaxValue</span> using the <span class="lang:c# decode:true crayon-inline ">Next</span> overload. Even worse, you can’t get any negative values. Similarly, <span class="lang:c# decode:true crayon-inline ">NextDouble</span> will only give you values greater than or equal to 0.0 or less than 1.0, which is hardly the whole range of possible doubles!</p>
<p>If we really want to be thinking about random number generation, the really useful method is the <span class="lang:c# decode:true crayon-inline ">NextBytes</span> method – and I’m going to flog it to death!</p>
<p>So first of all, what makes a good random ‘thing’ generator. Well priorities change based on application but at the top of my list is always “It must be theoretically possible to get every conceivable value” – this isn’t always achievable, but it’s the main goal for my implementations. After that, I normally place “It mustn’t be slow”, and finally, “Uniform distribution of values would be nice”. However, I don’t personally put uniformity ahead of performance.</p>
<p>I know in this regard I’m not going to get everyone’s agreement, however, in justification bare in mind that to actually get a random generator to give every possible long (by way of example) randomly would take so incredibly long that it’s uniformity is not that useful.</p>
<p>Ahead of everything, though, I want my Random number generators to be thread safe, and <a href="https://docs.microsoft.com/en-us/dotnet/api/system.random?redirectedfrom=MSDN&amp;view=netframework-4.8">System.Random</a> certainly isn’t (yet so many people miss that). The safest way to use a random is to declare a new one just before it’s use – but that creates a load of objects that need garbage collection. Way better is to have one Random per thread of execution – that way you don’t have to worry about locking, as a thread can’t interrupt itself.</p>
<p>Now achieving this scenario used to be a lot harder than it is in .NET 4 – now it’s easy &#8211;</p>
<pre class="lang:c# decode:true mixed:false">/// &lt;summary&gt;
/// Creates one random generator per thread.
/// &lt;/summary&gt;
[NotNull] private static readonly ThreadLocal&lt;Random&gt; _randomGenerators =
  new ThreadLocal&lt;Random&gt;(() =&gt; new Random());

/// &lt;summary&gt;
/// A random number generator.
/// &lt;/summary&gt;
[NotNull] public static Random RandomGenerator
{
  get
  {
  return _randomGenerators.Value;
  }
}</pre>
<p>The key here is the wonderful new <a href="https://docs.microsoft.com/en-us/dotnet/api/system.threading.threadlocal-1?redirectedfrom=MSDN&amp;view=netframework-4.8">System.Threading.ThreadLocal</a> generic class. This allows us to create a field that has a different value on each thread (which is created by the lambda expression), so we can get a different <span class="lang:c# decode:true crayon-inline">Random</span> on each thread – but only one per thread!</p>
<p>Now that I’ve solved thread safety let’s get on with creating our generators. For this, I want to add <a href="https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/extension-methods">extension methods</a> to the <a href="https://docs.microsoft.com/en-us/dotnet/api/system.random?redirectedfrom=MSDN&amp;view=netframework-4.8">System.Random</a> class, so I’m going to need a static class. to define them in (which in my project is called <span class="lang:c# decode:true crayon-inline ">Tester</span> as it’s part of my testing NuGet).</p>
<p>So let’s start with some easy ones &#8211;</p>
<pre class="lang:c# decode:true mixed:false">/// &lt;summary&gt;
/// Generates a random boolean.
/// &lt;/summary&gt;
/// &lt;param name="random"&gt;The random generator.&lt;/param&gt;
/// &lt;returns&gt;&lt;/returns&gt;
/// &lt;remarks&gt;&lt;/remarks&gt;
public static bool RandomBoolean(this Random random )
{
  return (random ?? RandomGenerator).Next(2) == 1;
}

/// &lt;summary&gt;
/// Generates a random byte.
/// &lt;/summary&gt;
/// &lt;param name="random"&gt;The random generator.&lt;/param&gt;
/// &lt;returns&gt;&lt;/returns&gt;
/// &lt;remarks&gt;&lt;/remarks&gt;
public static byte RandomByte(this Random random)
{
  return (byte) (random ?? RandomGenerator).Next(0x100);
}

/// &lt;summary&gt;
/// Generates a random char.
/// &lt;/summary&gt;
/// &lt;param name="random"&gt;The random generator.&lt;/param&gt;
/// &lt;returns&gt;&lt;/returns&gt;
/// &lt;remarks&gt;&lt;/remarks&gt;
public static char RandomChar(this Random random)
{
  return (char) (random ?? RandomGenerator).Next(0x10000);
}</pre>
<p>These classes us our good old <span class="lang:c# decode:true crayon-inline ">Random.Next</span> to create simple types, being careful to remember that the upper bound is exclusive (and that chars are Unicode!). If you call the methods directly (i.e. not as <a href="https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/extension-methods">extension methods</a>) and pass in null, they will use the RandomGenerator defined above, otherwise you can specify your own Random object.</p>
<p>Now we can turn our attention to creating a random integer, that can have every possible value &#8211;</p>
<pre class="lang:c# decode:true mixed:false">/// &lt;summary&gt;
/// Generates a random Int32.
/// &lt;/summary&gt;
/// &lt;param name="random"&gt;The random generator.&lt;/param&gt;
/// &lt;returns&gt;&lt;/returns&gt;
/// &lt;remarks&gt;&lt;/remarks&gt;
public static int RandomInt32(this Random random)
{
  byte[] bytes = new byte[4];
  (random ?? RandomGenerator).NextBytes(bytes);
  return BitConverter.ToInt32(bytes, 0);
}</pre>
<p>This method creates a 4-byte array and fills it with random bytes using the built-in random generator. Unlike <span class="lang:c# decode:true crayon-inline">Random.Next</span> , it gives a uniform distribution of every possible <span class="lang:c# decode:true crayon-inline ">Int32</span> value (including <span class="lang:c# decode:true crayon-inline ">Int32.MaxValue</span> and negatives).</p>
<p>We can extend the same principle to quite a few other types &#8211;</p>
<pre class="lang:c# decode:true mixed:false">/// &lt;summary&gt;
/// Generates a random Int16.
/// &lt;/summary&gt;
/// &lt;param name="random"&gt;The random generator.&lt;/param&gt;
/// &lt;returns&gt;&lt;/returns&gt;
/// &lt;remarks&gt;&lt;/remarks&gt;
public static short RandomInt16(this Random random)
{
  byte[] bytes = new byte[2];
  (random ?? RandomGenerator).NextBytes(bytes);
  return BitConverter.ToInt16(bytes, 0);
}

/// &lt;summary&gt;
/// Generates a random Int64.
/// &lt;/summary&gt;
/// &lt;param name="random"&gt;The random generator.&lt;/param&gt;
/// &lt;returns&gt;&lt;/returns&gt;
/// &lt;remarks&gt;&lt;/remarks&gt;
public static long RandomInt64(this Random random)
{
  byte[] bytes = new byte[8];
  (random ?? RandomGenerator).NextBytes(bytes);
  return BitConverter.ToInt64(bytes, 0);
}

/// &lt;summary&gt;
/// Generates a random float.
/// &lt;/summary&gt;
/// &lt;param name="random"&gt;The random generator.&lt;/param&gt;
/// &lt;returns&gt;&lt;/returns&gt;
/// &lt;remarks&gt;&lt;/remarks&gt;
public static float RandomFloat(this Random random)
{
  byte[] bytes = new byte[4];
  (random ?? RandomGenerator).NextBytes(bytes);
  return BitConverter.ToSingle(bytes, 0);
}

/// &lt;summary&gt;
/// Generates a random double.
/// &lt;/summary&gt;
/// &lt;param name="random"&gt;The random generator.&lt;/param&gt;
/// &lt;returns&gt;&lt;/returns&gt;
/// &lt;remarks&gt;&lt;/remarks&gt;
public static double RandomDouble(this Random random)
{
  byte[] bytes = new byte[8];
  (random ?? RandomGenerator).NextBytes(bytes);
  return BitConverter.ToDouble(bytes, 0);
}</pre>
<p>As you can see our new <span class="lang:c# decode:true crayon-inline ">RandomDouble</span> covers the whole double range, unlike <span class="lang:c# decode:true crayon-inline ">Random.NextDouble()</span> which is a nice result.</p>
<p>The next few types are going to get a little more tricky and require us to know something about their underlying implementations, for example, the decimal type. This can be constructed with four integers, but the last one is a bit special as it encodes a scale and a sign, and not all values are allowed (or possible) &#8211;</p>
<pre class="lang:c# decode:true mixed:false">/// &lt;summary&gt;
/// Generates a random decimal.
/// &lt;/summary&gt;
/// &lt;param name="random"&gt;The random generator.&lt;/param&gt;
/// &lt;returns&gt;&lt;/returns&gt;
/// &lt;remarks&gt;&lt;/remarks&gt;
public static decimal RandomDecimal(this Random random)
{
  random = random ?? RandomGenerator;

  // Calculate last byte
  // We need a scale from 0-28 and a sign, so calculate a random number between -28 &amp; 28.
  // This makes +'ves sligthly more common (as 0 is positive) but is faster.
  int scale = -28 + random.Next(57);
  int sign = 0;
  if (scale &lt; 0)
  {
  sign = unchecked((int) 0x80000000);
  scale = -scale;
  }

  // Now we can create msb.
  int msb = sign + (scale &lt;&lt; 16);

  return
  new decimal(new[]
  {
  random.RandomInt32(),
  random.RandomInt32(),
  random.RandomInt32(),
  msb
  });
}</pre>
<p>The first three integers are generated using our previous <span class="lang:c# decode:true crayon-inline ">RandomInt32</span> method, but the last integer is calculated separately to ensure it’s always valid. We have to apply the same level of care to the <span class="lang:c# decode:true crayon-inline ">DateTime</span> generators &#8211;</p>
<pre class="lang:c# decode:true mixed:false">/// &lt;summary&gt;
/// Generates a random date time, with a specific &lt;see cref="DateTimeKind" /&gt;.
/// &lt;/summary&gt;
/// &lt;param name="random"&gt;The random generator.&lt;/param&gt;
/// &lt;param name="kind"&gt;The &lt;see cref="DateTimeKind" /&gt;.&lt;/param&gt;
/// &lt;returns&gt;&lt;/returns&gt;
/// &lt;remarks&gt;&lt;/remarks&gt;
public static DateTime RandomDateTime(this Random random, DateTimeKind kind)
{
  // Last two bits are used internally by date time.
  long ticks = RandomInt64(random) &amp; 0x3FFFFFFFFFFFFFFF;

  // If ticks is more than max value, just and it to ensure less than max value.
  if (ticks &gt; 0x2bca2875f4373fff)
  ticks &amp;= 0x2bca2875f4373fff;

  return new DateTime(ticks, kind);
}

/// &lt;summary&gt;
/// Generates a random date time.
/// &lt;/summary&gt;
/// &lt;param name="random"&gt;The random generator.&lt;/param&gt;
/// &lt;returns&gt;&lt;/returns&gt;
/// &lt;remarks&gt;Also generates a random &lt;see cref="DateTimeKind" /&gt;.&lt;/remarks&gt;
public static DateTime RandomDateTime(this Random random)
{
  random = random ?? RandomGenerator;
  // Last two bits are used internally by date time.
  long ticks = RandomInt64(random) &amp; 0x3FFFFFFFFFFFFFFF;

  // If ticks is more than max value, just and it to ensure less than max value.
  if (ticks &gt; 0x2bca2875f4373fff)
  ticks &amp;= 0x2bca2875f4373fff;

  DateTimeKind kind;
  switch (random.Next(3))
  {
  case 0:
  kind = DateTimeKind.Utc;
  break;
  case 1:
  kind = DateTimeKind.Local;
  break;
  default:
  kind = DateTimeKind.Unspecified;
  break;
  }

  return new DateTime(ticks, kind);
}

/// &lt;summary&gt;
/// Generates a random date time.
/// &lt;/summary&gt;
/// &lt;param name="random"&gt;The random generator.&lt;/param&gt;
/// &lt;returns&gt;&lt;/returns&gt;
/// &lt;remarks&gt;Also generates a random &lt;see cref="DateTimeKind" /&gt;.&lt;/remarks&gt;
public static DateTimeOffset RandomDateTimeOffset(this Random random)
{
  random = random ?? RandomGenerator;
  // Last two bits are used internally by date time.
  long ticks = random.RandomInt64() &amp; 0x3FFFFFFFFFFFFFFF;

  // If ticks is more than max value, just and it to ensure less than max value.
  if (ticks &gt; 0x2bca2875f4373fff)
  ticks &amp;= 0x2bca2875f4373fff;

  // Calculate random offset +/- 14 hours in minutes (offsets must be in minutes)
  long offsetTicks = (TimeSpan.TicksPerHour*-14) + (TimeSpan.TicksPerMinute*random.Next(1680));

  // Ensure offsetTicks don't take us outside of the DateTime range.
  // We could decrease/increase ticks and round to nearest minute, but it is easier just to set to 0.
  long ticksOffset = offsetTicks - ticks;
  if ((ticksOffset &lt; 0) ||
  (ticksOffset &gt; 0x2bca2875f4373fff)) offsetTicks = 0;

  return new DateTimeOffset(ticks, TimeSpan.FromTicks(offsetTicks));
}</pre>
<p>These required a lot more thought but they’ve been thoroughly tested and checked, so feel free to use them even if the comments aren’t immediately transparent to you!</p>
<p>Finally, we probably want to be able to generate random strings &#8211;</p>
<pre class="lang:c# decode:true mixed:false">/// &lt;summary&gt;
/// Generates a random string.
/// &lt;/summary&gt;
/// &lt;param name="random"&gt;The random generator.&lt;/param&gt;
/// &lt;param name="maxLength"&gt;Maximum length.&lt;/param&gt;
/// &lt;param name="unicode"&gt;if set to &lt;see langword="true" /&gt; string is UTF16; otherwise it uses ASCII.&lt;/param&gt;
/// &lt;param name="nullProbability"&gt;The probability of a null being returned (0.0 for no nulls).&lt;/param&gt;
/// &lt;returns&gt;&lt;/returns&gt;
/// &lt;remarks&gt;&lt;/remarks&gt;
public static string RandomString(this Random random, int maxLength = -1, bool unicode = true, double nullProbability = 0.0)
{
  random = random ?? RandomGenerator;
  // Check for random nulls
  if ((nullProbability &gt; 0.0) &amp;&amp;
  (random.NextDouble() &lt; nullProbability))
  return null;

  // Get string length, if there's no maximum then use 8001 (as 8000 is max specific size in SQL Server).
  int length = (maxLength &lt; 0 ? random.Next(10000) : maxLength)*(unicode ? 2 : 1);
  if (length &lt; 1)
  return string.Empty;

  byte[] bytes = new byte[length];
  random.NextBytes(bytes);
  return unicode ? new UnicodeEncoding().GetString(bytes) : new ASCIIEncoding().GetString(bytes);
}</pre>
<p>The <span class="lang:c# decode:true crayon-inline ">nullProbability</span> allows you to optionally (and randomly) return nulls, and Unicode is likewise optional.</p>
<p>Next time, we’ll start looking at some more random generators related to SQL, but before we finish, how about something a bit different? The next two extensions are to the IEnumerable&lt;T&gt; interface, which extends the built-in LINQ queries to include a random item selector &#8211;</p>
<pre class="lang:c# decode:true mixed:false">/// &lt;summary&gt;
/// Returns a random element from an enumeration, that matches the predicate; otherwise returns the default value.
/// &lt;/summary&gt;
/// &lt;typeparam name="T"&gt;The element type.&lt;/typeparam&gt;
/// &lt;param name="enumeration"&gt;The enumeration.&lt;/param&gt;
/// &lt;param name="predicate"&gt;The optional predicate.&lt;/param&gt;
/// &lt;returns&gt;A random element or default.&lt;/returns&gt;
[CanBeNull]
public static T RandomOrDefault&lt;T&gt;([NotNull]this IEnumerable&lt;T&gt; enumeration, Func&lt;T, bool&gt; predicate = null)
{
  if (enumeration == null)
  throw new ArgumentNullException("enumeration", "The enumeration cannot be null.");

  // We may as well build a list, as we have to count elements anyway.
  List&lt;T&gt; filtered = predicate == null ? enumeration.ToList() : enumeration.Where(predicate).ToList();

  int count = filtered.Count;
  return count &lt; 1 ? default(T) : filtered[RandomGenerator.Next(count)];
}

/// &lt;summary&gt;
/// Returns a random element from an enumeration, that matches the predicate; otherwise throws an exception if the predicate is not matched.
/// &lt;/summary&gt;
/// &lt;typeparam name="T"&gt;The element type.&lt;/typeparam&gt;
/// &lt;param name="enumeration"&gt;The enumeration.&lt;/param&gt;
/// &lt;param name="predicate"&gt;The optional predicate.&lt;/param&gt;
/// &lt;returns&gt;A random element.&lt;/returns&gt;
[CanBeNull]
public static T Random&lt;T&gt;([NotNull]this IEnumerable&lt;T&gt; enumeration, Func&lt;T, bool&gt; predicate = null)
{
  if (enumeration == null)
  throw new ArgumentNullException("enumeration", "The enumeration cannot be null.");

  // We may as well build a list, as we have to count elements anyway.
  List&lt;T&gt; filtered = predicate == null ? enumeration.ToList() : enumeration.Where(predicate).ToList();

  int count = filtered.Count;
  if (count &lt; 1)
  throw new InvalidOperationException("The enumeration did not return any results.");
  return filtered[RandomGenerator.Next(count)];
}</pre>
<p>If you want any clarification, or you have a better implementation be sure to leave a comment! Once I get through these tutorials I’ll be sure to post the completed source.</p>
</div>
<h3>Related Images:</h3>
<p> [<a href="https://thargy.com/2012/04/generating-randomness/">See image gallery at thargy.com</a>] </p>
]]></content:encoded>
					
					<wfw:commentRss>https://thargy.com/2012/04/generating-randomness/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">168</post-id>	</item>
		<item>
		<title>The problem with null checking</title>
		<link>https://thargy.com/2012/04/the-problem-with-null-checking/</link>
					<comments>https://thargy.com/2012/04/the-problem-with-null-checking/#comments</comments>
		
		<dc:creator><![CDATA[thargy]]></dc:creator>
		<pubDate>Sun, 29 Apr 2012 17:20:30 +0000</pubDate>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Reflection]]></category>
		<category><![CDATA[Code Contracts]]></category>
		<category><![CDATA[Null]]></category>
		<category><![CDATA[PostSharp]]></category>
		<category><![CDATA[ReSharper]]></category>
		<guid isPermaLink="false">http://thargy.com/?p=156</guid>

					<description><![CDATA[The .NET framework is littered with the following code (e.g. from the System.Guid class): public static Guid ParseExact(String input, String format) { if (input == null) throw new ArgumentNullException("input"); if (format == null) throw new ArgumentNullException("format"); if (format.Length != 1) { // all acceptable format strings are of length 1 throw new FormatException(…); } … ...]]></description>
										<content:encoded><![CDATA[<div class="entry">
<p>The .NET framework is littered with the following code (e.g. from the <a href="https://docs.microsoft.com/en-us/dotnet/api/system.guid?redirectedfrom=MSDN&amp;view=netframework-4.8" target="_blank" rel="noopener noreferrer">System.Guid</a> class):</p>
<pre class="lang:csharp mark:3,6,9 decode:true mixed:false">public static Guid ParseExact(String input, String format)
{
    if (input == null)
        throw new ArgumentNullException("input");

    if (format == null)
        throw new ArgumentNullException("format");

    if (format.Length != 1)
    {
        // all acceptable format strings are of length 1
        throw new FormatException(…);
    }
    …
}
</pre>
<p>A common scenario when creating a publicly accessible method is to validate the parameters being passed into the method and throw an exception when something is amiss.&nbsp; I used this example as <a href="https://docs.microsoft.com/en-us/dotnet/api/system.guid.parseexact?redirectedfrom=MSDN&amp;view=netframework-4.8" target="_blank" rel="noopener noreferrer">Guid.ParseExact</a> was only added in .NET 4, showing that this is still the ‘Microsoft way’.</p>
<p>But when you do this all over the framework it impacts on performance.&nbsp; The reality is that in the vast majority of cases this code should be called with a valid string representation of a Guid, at least with a non-null string (with length &gt; 0), yet we have to do the checks every time the method is called.&nbsp; Even if I can be certain the string represents a real Guid, there is no way for me to skip these checks.&nbsp; You might say that’s not really a problem, but if I’m writing an ORM (for example) and I’m looking for raw object creation throughput, that overhead starts to become significant.</p>
<p>When <a href="https://www.jetbrains.com:443/resharper/" target="_blank" rel="noopener noreferrer">ReSharper</a> looked at this problem, they realised that it would be possible to indicate whether null values were expected or not using attributes.&nbsp; For that reason they added a bunch of <a href="https://www.jetbrains.com:443/help/resharper/2016.2/Code_Analysis__External_Annotations.html" target="_blank" rel="noopener noreferrer">attributes</a> that they use to inform their value analysis module, and then they went through the framework and effectively marked it all up.&nbsp; If you’re using <a href="https://www.jetbrains.com:443/resharper/" target="_blank" rel="noopener noreferrer">ReSharper</a> (and if not, why not?) you can make use of this code analysis by modifying the above code:</p>
<pre class="lang:csharp mark:1 decode:true mixed:false">public static Guid ParseExact(
    [NotNull]String input,
    [NotNull]String format)
{
    if (format.Length != 1)
    {
        // all acceptable format strings are of length 1
        throw new FormatException(…);
    }
    …
}
</pre>
<p><a href="https://www.jetbrains.com:443/resharper/" target="_blank" rel="noopener noreferrer">ReSharper</a> will test any code that uses ParseExact and provide a helpful squiggle if it things you are passing in a null when you shouldn’t be.&nbsp; To be fair the intent here is not to remove the checks themselves, but to make their value analysis not bug you with warnings when they’re unnecessary, but the temptation to remove the checks is powerful.&nbsp; But this has two big problems.</p>
<ol>
<li>What is the person using your library doesn’t have <a href="https://www.jetbrains.com:443/resharper/" target="_blank" rel="noopener noreferrer">ReSharper</a>?
<li>What if the person using your library ignores the squiggle?</li>
</ol>
<p>What <a href="https://www.jetbrains.com:443/resharper/" target="_blank" rel="noopener noreferrer">ReSharper</a> is doing is pretty smart, by analysing the code it can tell if it’s possible a null is sneaking through.&nbsp; This isn’t done by running the code, but rather by analysing paths through the code.&nbsp; This can be done at compile time – though it’s not always bomb proof.&nbsp; When <a href="https://www.microsoft.com/en-us/research/" target="_blank" rel="noopener noreferrer">Microsoft Research</a> approached this problem they came up with an even better solution – <a href="https://www.microsoft.com/en-us/research/project/code-contracts/" target="_blank" rel="noopener noreferrer">Code Contracts</a>.</p>
<p>With <a href="https://www.microsoft.com/en-us/research/project/code-contracts/" target="_blank" rel="noopener noreferrer">Code Contracts</a> enabled it is possible to rewrite the above like so :</p>
<pre class="lang:csharp decode:true mixed:false">public static Guid ParseExact(String input, String format)
{
    Contract.Requires(input != null);
    Contract.Requires(format != null);
    Contract.Requires(format.Length != 1);
    ...
}
</pre>
<p>Which looks eerily like Debug.Assert or Assert.IsTrue statements.&nbsp; Unlike those two examples though the Contract namespace includes methods that effectively run at compile time to validate constraints.&nbsp; These methods can also optionally run at runtime, which is useful when a constraint cannot be fully validated at compile time.&nbsp; Using contracts allows us to move away from those chains of parameter validation code safely.&nbsp; It even lets us provide information about the outputs of the method using the Contract.Ensures method.&nbsp; This is a hugely powerful tool in the .NET developer’s arsenal.</p>
<p><a href="https://i0.wp.com/thargy.com/wp-content/uploads/2012/04/image2.png"><img data-recalc-dims="1" loading="lazy" decoding="async" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" align="right" src="https://i0.wp.com/thargy.com/wp-content/uploads/2012/04/image_thumb2.png?resize=244%2C239" width="244" height="239"></a>But it still suffers from a similar problem to the <a href="https://www.jetbrains.com:443/resharper/" target="_blank" rel="noopener noreferrer">ReSharper</a> solution – what if the person using your library doesn’t use <a href="https://www.microsoft.com/en-us/research/project/code-contracts/" target="_blank" rel="noopener noreferrer">Code Contracts</a>?&nbsp; Also, unlike <a href="https://www.jetbrains.com:443/resharper/" target="_blank" rel="noopener noreferrer">ReSharper</a>, it also modifies the assembly at build time which can be buggy when using other tools, such as <a href="https://www.postsharp.net/" target="_blank" rel="noopener noreferrer">PostSharp</a>.&nbsp;&nbsp; The final nail in the coffin is that <a href="https://www.jetbrains.com:443/resharper/" target="_blank" rel="noopener noreferrer">ReSharper</a> just doesn’t support <a href="https://www.microsoft.com/en-us/research/project/code-contracts/" target="_blank" rel="noopener noreferrer">Code Contracts</a> in any useful way, and so you’re left implementing both.&nbsp; It’s for this reason I have repeatedly come back to <a href="https://www.microsoft.com/en-us/research/project/code-contracts/" target="_blank" rel="noopener noreferrer">Code Contracts</a> over the last few years and debated whether to include it in projects.</p>
<p>However, the community does seem to be swinging towards it’s adoption and .NET 4.5 includes the <a href="https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.contracts?redirectedfrom=MSDN&amp;view=netframework-4.8" target="_blank" rel="noopener noreferrer">System.Diagnostics.Contract namespace</a> out of the box – but you currently still need to install the <a href="https://marketplace.visualstudio.com/items?itemName=RiSEResearchinSoftwareEngineering.CodeContractsforNET" target="_blank" rel="noopener noreferrer">Code Contracts extension</a> into <a href="https://visualstudio.microsoft.com/" target="_blank" rel="noopener noreferrer">VS11</a> beta if you want to configure it (note if you’re using <a href="https://visualstudio.microsoft.com/" target="_blank" rel="noopener noreferrer">VS11</a> that you currently also have to execute ‘devenv /setup’ to complete installation which is a bit of a mess).&nbsp; If you’re targeting the new framework then there’s no reason to not include <a href="https://www.microsoft.com/en-us/research/project/code-contracts/" target="_blank" rel="noopener noreferrer">Code Contracts</a> as you’re end users won’t have compilation problems – but you may want to encourage them to set up their projects to make use of the contracts you define.&nbsp; Maybe the Visual Studio team will include the extension when <a href="https://visualstudio.microsoft.com/" target="_blank" rel="noopener noreferrer">VS11</a> goes RTM, but that’s not clear.</p>
<p>Until they do, sometimes my code will include examples whilst other times you’ll see the <a href="https://www.jetbrains.com:443/resharper/" target="_blank" rel="noopener noreferrer">ReSharper</a> attributes.&nbsp; if you struggle compiling the code you can <a href="https://www.jetbrains.com:443/help/resharper/2016.2/Code_Analysis__External_Annotations.html" target="_blank" rel="noopener noreferrer">read the following article</a>, or <a href="https://www.nuget.org/packages/adjunct-JetBrains.Annotations.Core" target="_blank" rel="noopener noreferrer">install the Nuget</a>.&nbsp; If you want to go old school just create fake attributes that match the signatures used.&nbsp; If all else fails, you can safely delete the attributes.</p>
</div>
<h3>Related Images:</h3>
<p> [<a href="https://thargy.com/2012/04/the-problem-with-null-checking/">See image gallery at thargy.com</a>] </p>
]]></content:encoded>
					
					<wfw:commentRss>https://thargy.com/2012/04/the-problem-with-null-checking/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">156</post-id>	</item>
		<item>
		<title>Real-time site monitoring</title>
		<link>https://thargy.com/2012/04/real-time-site-monitoring/</link>
		
		<dc:creator><![CDATA[thargy]]></dc:creator>
		<pubDate>Fri, 27 Apr 2012 07:06:26 +0000</pubDate>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Personal]]></category>
		<category><![CDATA[CloudFlare]]></category>
		<category><![CDATA[DNS]]></category>
		<category><![CDATA[GoDaddy]]></category>
		<category><![CDATA[Migration]]></category>
		<category><![CDATA[PingDom]]></category>
		<category><![CDATA[Statistics]]></category>
		<guid isPermaLink="false">http://thargy.com/?p=154</guid>

					<description><![CDATA[CloudFlare has saved my neck, repeatedly.  As regular readers no I have been migrating my domains to a new host, for all the advantages of using a big name like GoDaddy.com, there are an equal number of disadvantages.  However, using CloudFlare has meant that I can use their nameservers, which has allowed me to work ...]]></description>
										<content:encoded><![CDATA[<div class="entry">
<p><a href="https://www.cloudflare.com/" target="_blank" rel="noopener noreferrer">CloudFlare</a> has saved my neck, repeatedly.  As regular readers no I have been <a href="http://thargy.com/2012/04/there-may-be-trouble-ahead/">migrating my domains to a new host</a>, for all the advantages of using a big name like <a href="https://www.godaddy.com/" target="_blank" rel="noopener noreferrer">GoDaddy.com</a>, there are an equal number of disadvantages.  However, using <a href="https://www.cloudflare.com/" target="_blank" rel="noopener noreferrer">CloudFlare</a> has meant that I can use their nameservers, which has allowed me to work around most of the idiosyncrasies of my existing registrars, and my new registrar/host.</p>
<p>But even better is the amazing site acceleration that it provides &#8211; and that’s good as <a href="https://www.godaddy.com/" target="_blank" rel="noopener noreferrer">GoDaddy.com</a> is <em>noticeably </em>slower than my previous host.  With it’s built in CDN, <a href="https://www.cloudflare.com/" target="_blank" rel="noopener noreferrer">CloudFlare</a> provides super fast content to my visitors, and best of all, it works hand in hand with the excellent <a href="https://www.w3-edge.com/products/w3-total-cache/" target="_blank" rel="noopener noreferrer">W3 Total Cache</a> plugin.</p>
<p><a href="https://www.cloudflare.com/" target="_blank" rel="noopener noreferrer">CloudFlare</a> doesn’t stop there though, it has fantastic security features, and best of all, it has apps!  One of the ones I really like is <a href="https://www.pingdom.com/" target="_blank" rel="noopener noreferrer">PingDom</a> which allows for real-time monitoring of a domain, and it even sends SMS/email if your site is down.</p>
<p>Because my DNS hosting and <a href="https://www.pingdom.com/" target="_blank" rel="noopener noreferrer">PingDom</a> are independent of <a href="https://www.godaddy.com/" target="_blank" rel="noopener noreferrer">GoDaddy.com</a>, my visitors, and I, can check the sites status automatically with stats.thargy.com (<strong>UPDATE</strong>: PingDom have removed public reports on free accounts), which should stay up even if everything else is dead.</p>
<p><a href="https://i0.wp.com/thargy.com/wp-content/uploads/2012/04/PingDom.png"><img data-recalc-dims="1" loading="lazy" decoding="async" style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="PingDom" src="https://i0.wp.com/thargy.com/wp-content/uploads/2012/04/PingDom_thumb.png?resize=644%2C443" alt="PingDom" width="644" height="443" border="0" /></a></p>
<p>That’s a good thing as I wait for the final transfer of my domains which can happen anytime in the next five days.</p>
</div>
<h3>Related Images:</h3>
<p> [<a href="https://thargy.com/2012/04/real-time-site-monitoring/">See image gallery at thargy.com</a>] </p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">154</post-id>	</item>
		<item>
		<title>There may be trouble ahead</title>
		<link>https://thargy.com/2012/04/there-may-be-trouble-ahead/</link>
					<comments>https://thargy.com/2012/04/there-may-be-trouble-ahead/#comments</comments>
		
		<dc:creator><![CDATA[thargy]]></dc:creator>
		<pubDate>Tue, 24 Apr 2012 23:04:32 +0000</pubDate>
				<category><![CDATA[Personal]]></category>
		<guid isPermaLink="false">http://thargy.com/?p=135</guid>

					<description><![CDATA[OK I&#8217;m not going to lie to you, there&#8217;s no way to sugar coat this&#8230; I despise the Domain Registration system. Can&#8217;t help myself. I&#8217;ve owned thargy.com and unclecraig.com for well over 10 years and every year I go through the same renewal hell of trying to figure out who owns what &#8211; requesting transfers ...]]></description>
										<content:encoded><![CDATA[<div class="entry">
<p><img data-recalc-dims="1" loading="lazy" decoding="async" class="alignright size-thumbnail wp-image-136" title="Unhappy Network Admin" src="https://i0.wp.com/thargy.com/wp-content/uploads/2012/04/unhappy_network_admin-150x150.jpg?resize=150%2C150" alt="An unhappy network administrator." width="150" height="150" srcset="https://i0.wp.com/thargy.com/wp-content/uploads/2012/04/unhappy_network_admin.jpg?resize=150%2C150&amp;ssl=1 150w, https://i0.wp.com/thargy.com/wp-content/uploads/2012/04/unhappy_network_admin.jpg?zoom=2&amp;resize=150%2C150&amp;ssl=1 300w, https://i0.wp.com/thargy.com/wp-content/uploads/2012/04/unhappy_network_admin.jpg?zoom=3&amp;resize=150%2C150&amp;ssl=1 450w" sizes="auto, (max-width: 150px) 100vw, 150px" /></p>
<p>OK I&#8217;m not going to lie to you, there&#8217;s no way to sugar coat this&#8230;</p>
<p><em>I despise the Domain Registration system.</em></p>
<p>Can&#8217;t help myself.  I&#8217;ve owned thargy.com and unclecraig.com for well over 10 years and every year I go through the same renewal hell of trying to figure out who owns what &#8211; requesting transfers and all the unnecessarily messy rubbish that the industry subjects it&#8217;s users to.   It&#8217;s not that I&#8217;m a &#8216;search for the cheapest deal&#8217; masochist, it&#8217;s purely that I have a great habit of backing losers when it comes to the great registrar consolidation world war that has raged continuously over the last decade.  I have genuinely lost count of the times that one of my registrars or hosts has changed hands, such that my host, and domains all exist with different people.  I genuinely hate Domain Registration.</p>
<p>Well enough is enough, I&#8217;ve finally decided to combine everything onto <a title="GoDaddy.com" href="https://www.godaddy.com/" target="_blank">GoDaddy.com</a>.  I strongly suspect this is a decision I will live to regret (going on previous form) and certainly my initial experience has been somewhat typically hellish.  After many hours of work, numerous support tickets raised, etc. (at one point I even got sent a completely blank EPP Key/Authorization Key in a friendly email) I have at least registered my transfer of thargy.com and have attempted to begin the process of transferring unclecraig.com (though success there remains firmly in the balance).</p>
<p>I am hoping to move this WordPress to GoDaddy, and transfer everything (including <a title="CloudFlare" href="https://www.cloudflare.com/" target="_blank">CloudFlare</a> CDN support) over in the next week.  I figure there&#8217;s no time like the present, after all my subscriber count is still very low.</p>
<p>With luck there will be no noticeable interruption, however if the inevitable happens and the site is down, please bare with me as I hope to get it back up and running as soon as possible!</p>
<p>I have some great blogs posts planned for when everything settles down so I hope your persevere.</p>
</div>
<h3>Related Images:</h3>
]]></content:encoded>
					
					<wfw:commentRss>https://thargy.com/2012/04/there-may-be-trouble-ahead/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">135</post-id>	</item>
		<item>
		<title>Oldham is great</title>
		<link>https://thargy.com/2012/04/oldham-is-great/</link>
		
		<dc:creator><![CDATA[thargy]]></dc:creator>
		<pubDate>Tue, 24 Apr 2012 15:56:00 +0000</pubDate>
				<category><![CDATA[Chamber of Commerce]]></category>
		<category><![CDATA[Management]]></category>
		<category><![CDATA[Mahdlo]]></category>
		<category><![CDATA[Metrolink]]></category>
		<category><![CDATA[Oldham]]></category>
		<category><![CDATA[Oldham College]]></category>
		<category><![CDATA[Oldham Sixth Form College]]></category>
		<category><![CDATA[Printworks]]></category>
		<category><![CDATA[Queen Elizabeth Hall]]></category>
		<guid isPermaLink="false">http://thargy.com/?p=256</guid>

					<description><![CDATA[Update:&#160;This post has now appeared in the Oldham Chronicle as can be seen on the Web Apps Website. In Oldham we seem to find it easy to focus on the negatives, but having attended a number of events showcasing plans for regeneration, it’s difficult to feel anything but positive. Oldham is pushing forward, to show ...]]></description>
										<content:encoded><![CDATA[<div class="entry">
<p><a href="https://i0.wp.com/thargy.com/wp-content/uploads/2012/05/OldhamUnveilingWW1Memorial.jpg"><img data-recalc-dims="1" loading="lazy" decoding="async" style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; float: right; padding-top: 0px; border: 0px;" title="OldhamUnveilingWW1Memorial" src="https://i0.wp.com/thargy.com/wp-content/uploads/2012/05/OldhamUnveilingWW1Memorial_thumb.jpg?resize=244%2C156" alt="OldhamUnveilingWW1Memorial" width="244" height="156" align="right" border="0"></a></p>
<p><em><strong>Update:&nbsp;</strong>This post has now appeared in the Oldham Chronicle as can be seen on the Web Apps Website.</em></p>
<p>In Oldham we seem to find it easy to focus on the negatives, but having attended a number of events showcasing plans for regeneration, it’s difficult to feel anything but positive. Oldham is pushing forward, to show that it’s no longer a dusty old mill town but a place of real innovation and growth, bringing a brighter future to everyone in the borough.</p>
<p>This is exemplified by the recent opening of the <a href="https://www.mahdloyz.org/" target="_blank" rel="noopener noreferrer">Mahdlo</a> Youth Zone which aims to raise the aspirations of Oldham’s young people. Outstanding educational institutions such as <a href="https://www.osfc.ac.uk/" target="_blank" rel="noopener noreferrer">Oldham Sixth Form</a>, <a href="https://www.oldham.ac.uk/" target="_blank" rel="noopener noreferrer">Oldham College</a> and University Campus Oldham are ensuring a skilled workforce for the future. These skilled young workers won’t need to go far for incredible career opportunities either.</p>
<p>‘Invest in Oldham’ is a pro-active movement by Oldham Council to attract business to the area. At the launch event at Gallery Oldham in March, potential financiers were shown reasons why they should view Oldham differently: including its great location, great people, great infrastructure and great businesses.</p>
<p>It was here that the Hotel Future project, a luxury hotel doubling as a full time vocational training centre was unveiled. The £40 million project is a world first and will create hundreds of new jobs and apprenticeships for the area. The expected location is next to the <a href="https://queenelizabethhall.com/" target="_blank" rel="noopener noreferrer">Queen Elizabeth Hall</a> which will itself be renovated to create a new Civic Square rivalling Bolton’s Victoria Square and Manchester’s Albert Square.</p>
<p>Our Grade II listed Old Town Hall is currently part of restoration plans. In 2010, workmen began to repair the inhabitable building, creating a base for future developments. A range of options are now being considered, including a family facility similar to <a href="https://printworks-manchester.com/" target="_blank" rel="noopener noreferrer">Manchester’s Printworks</a>. It’s great to see the Council looking to regenerate rather than focusing on cutbacks.</p>
<p>By 2014 when these projects will be nearing completion, the new <a href="https://tfgm.com:443/public-transport/tram" target="_blank" rel="noopener noreferrer">Metrolink</a> will be in place; connecting Oldham to Central and Greater Manchester. Bringing great transport links to the town will encourage businesses to the area. The temporary line to Oldham Mumps is set to open very soon meaning Oldham’s infrastructure is steadily improving.</p>
<p>The next few years will be critical to restoring the prominence Oldham once held. These are exciting times for the entire borough and as Oldham president of the <a href="https://www.gmchamber.co.uk/" target="_blank" rel="noopener noreferrer">Greater Manchester Chamber of Commerce</a>, I welcome the fundamental changes needed to see the town flourish.</p>
<p>With the Olympic torch arriving in the borough on Sunday 24<sup>th</sup> June, let’s make sure the nation sees a positive Oldham focused on the future. We need to believe in our town, otherwise, who else will?</p>
<p>For more information about investment opportunities in Oldham see <a href="https://www.oldham.gov.uk/info/200692/invest_in_oldham">www.investinoldham.com</a> .</p>
</div>
<h3>Related Images:</h3>
<p> [<a href="https://thargy.com/2012/04/oldham-is-great/">See image gallery at thargy.com</a>] </p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">256</post-id>	</item>
		<item>
		<title>Delivering code as a team</title>
		<link>https://thargy.com/2012/04/delivering-code-as-a-team-2/</link>
					<comments>https://thargy.com/2012/04/delivering-code-as-a-team-2/#comments</comments>
		
		<dc:creator><![CDATA[thargy]]></dc:creator>
		<pubDate>Sun, 22 Apr 2012 09:40:00 +0000</pubDate>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Management]]></category>
		<category><![CDATA[Process]]></category>
		<category><![CDATA[1080p]]></category>
		<category><![CDATA[Agile]]></category>
		<category><![CDATA[Bugzilla]]></category>
		<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[Education]]></category>
		<category><![CDATA[FogBugz]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[Issue Tracking]]></category>
		<category><![CDATA[Kiln]]></category>
		<category><![CDATA[Lecture]]></category>
		<category><![CDATA[Manchester University]]></category>
		<category><![CDATA[PowerPoint]]></category>
		<category><![CDATA[Scrum]]></category>
		<category><![CDATA[Source Control]]></category>
		<category><![CDATA[University of Manchester]]></category>
		<category><![CDATA[Vegas Pro]]></category>
		<category><![CDATA[WMV]]></category>
		<guid isPermaLink="false">http://thargy.com/?p=117</guid>

					<description><![CDATA[Anyone who knows me will tell you how important I take any opportunity to talk to young people before they enter the workforce, so when the University of Manchester invited me to give a guest lecture to their Advanced Computer Science masters students I jumped at the chance. So at 11AM on Wednesday the 18th ...]]></description>
										<content:encoded><![CDATA[<div class="entry">
<p>Anyone who knows me will tell you how important I take any opportunity to talk to young people before they enter the workforce, so when the <a title="University of Manchester" href="https://www.manchester.ac.uk/" target="_blank" rel="noopener noreferrer">University of Manchester</a> invited me to give a guest lecture to their Advanced Computer Science masters students I jumped at the chance.</p>
<p>So at 11AM on Wednesday the 18th of April 2012 I found myself stood in front of an audience of approximately 30 students. I won’t lie to you, I’d had a very busy week, but this one hour was priority number one for me. The biggest problem was how to condense everything I wanted to say into just an hour – a near impossible task – and so, unsurprisingly I resorted to my usual technique of just talking <em>really</em> quickly! The results are less than impressive, but I think there’s some pretty important insights buried in there. I do regret not having more preparation time to nail down the timings but I think the message still came across OK.</p>
<p>Thankfully I took Gordon Pearce and Natalie Bailey along and Gordon helpfully recorded the whole thing on his <a title="The new iPad" href="https://www.apple.com/uk/ipad/" target="_blank" rel="noopener noreferrer">iPad</a> so you can see it below.</p>
<p><iframe loading="lazy" class="youtube-player" width="480" height="270" src="https://www.youtube.com/embed/XH5dPqPujKo?version=3&#038;rel=1&#038;showsearch=0&#038;showinfo=1&#038;iv_load_policy=1&#038;fs=1&#038;hl=en-GB&#038;autohide=2&#038;wmode=transparent" allowfullscreen="true" style="border:0;" sandbox="allow-scripts allow-same-origin allow-popups allow-presentation allow-popups-to-escape-sandbox"></iframe></p>
<p>You can also download the original <a title="PowerPoint" href="https://products.office.com/en-gb/powerpoint?legRedir=true&amp;CorrelationId=7e78a6be-8859-4c7d-8e2f-ba03316a0d76" target="_blank" rel="noopener noreferrer">PowerPoint</a> presentation <a title="Delivering code as a team PowerPoint." href="http://thargy.com/wp-content/uploads/2012/04/Delivering-code-as-a-team.pptx" rel="me noopener noreferrer" target="_blank">here</a>.</p>
<p>During the lecture I covered off a number of topics, including the kind of job graduates should look for. I feel it’s important that a first job should be working with other developers where you can refine your skills and learn your craft.</p>
<p>I then went on to talk about how developing code works in businesses, particularly client driven ones. Briefly, I introduced the concepts of <a title="Blog posts about process" href="http://thargy.com/category/process/" target="_blank" rel="noopener noreferrer">process</a>, issue tracking and source control.</p>
<p>The lecture is aimed at people who are just starting out in a career in IT and helps focus on some of the practicality that are often missing from a graduate’s repertoire.</p>
<p>The video was edited down in <a title="Sony Vegas Pro 11" href="https://www.vegascreativesoftware.com/us/vegas-pro/?utm_source=sonycreativesoftware&amp;utm_medium=referral&amp;utm_campaign=redirect&amp;lang=us&amp;prdt=vegaspro" target="_blank" rel="noopener noreferrer">Vegas Pro</a>. I was asked at the end of the lecture how the presentation had been done (with all the animations). It’s no secret that it was done entirely in <a title="PowerPoint" href="https://products.office.com/en-gb/powerpoint?legRedir=true&amp;CorrelationId=7e78a6be-8859-4c7d-8e2f-ba03316a0d76" target="_blank" rel="noopener noreferrer">PowerPoint</a>. For the video I reedited the aspect ratio from 4:3 to 16:9 to fit the widescreen and saved as <a title="Windows Media Video" href="https://en.wikipedia.org/wiki/Windows_Media_Video" target="_blank" rel="noopener noreferrer">WMV</a> – unfortunately the maximum resolution is 1280&#215;720 so I used <a title="Sony Vegas Pro 11" href="https://www.vegascreativesoftware.com/us/vegas-pro/?utm_source=sonycreativesoftware&amp;utm_medium=referral&amp;utm_campaign=redirect&amp;lang=us&amp;prdt=vegaspro" target="_blank" rel="noopener noreferrer">Vegas Pro</a> to upscale it to <a title="1080p (HD progressive video)" href="https://en.wikipedia.org/wiki/1080p" target="_blank" rel="noopener noreferrer">1080p</a>.</p>
</div>
<h3>Related Images:</h3>
<p> [<a href="https://thargy.com/2012/04/delivering-code-as-a-team-2/">See image gallery at thargy.com</a>] </p>
]]></content:encoded>
					
					<wfw:commentRss>https://thargy.com/2012/04/delivering-code-as-a-team-2/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">117</post-id>	</item>
		<item>
		<title>Statics and Generics</title>
		<link>https://thargy.com/2012/04/statics-and-generics/</link>
					<comments>https://thargy.com/2012/04/statics-and-generics/#comments</comments>
		
		<dc:creator><![CDATA[thargy]]></dc:creator>
		<pubDate>Fri, 13 Apr 2012 17:33:21 +0000</pubDate>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[dependency injection]]></category>
		<category><![CDATA[Fakes]]></category>
		<category><![CDATA[Generics]]></category>
		<category><![CDATA[OO]]></category>
		<category><![CDATA[Statics]]></category>
		<category><![CDATA[TDD]]></category>
		<guid isPermaLink="false">http://thargy.com/?p=89</guid>

					<description><![CDATA[So statics are generally considered evil, the enemy of TDD and IOC, and at odds with the purity of OO design. Shame they’re so incredibly fast! Whilst we’re talking about the TDD issue, I recommend you stop for a moment and go and take a look at the Fakes Framework added to VS11. Fakes is ...]]></description>
										<content:encoded><![CDATA[<div class="entry">
<p>So statics are generally <a href="http://codeliability.blogspot.com/2007/07/statics-are-evil.html" target="_blank" rel="noopener noreferrer">considered evil</a>, the enemy of <a href="https://en.wikipedia.org/wiki/Test-driven_development" target="_blank" rel="noopener noreferrer">TDD</a> and <a href="https://en.wikipedia.org/wiki/Inversion_of_control" target="_blank" rel="noopener noreferrer">IOC</a>, and at odds with the purity of <a href="https://en.wikipedia.org/wiki/Object-oriented_programming" target="_blank" rel="noopener noreferrer">OO</a> design. Shame they’re so incredibly fast!</p>
<p>Whilst we’re talking about the <a href="https://en.wikipedia.org/wiki/Test-driven_development" target="_blank" rel="noopener noreferrer">TDD</a> issue, I recommend you stop for a moment and go and take a look at the <a href="https://www.microsoft.com/en-us/research/project/moles-isolation-framework-for-net/" target="_blank" rel="noopener noreferrer">Fakes Framework</a> added to <a href="https://visualstudio.microsoft.com/" target="_blank" rel="noopener noreferrer">VS11</a>. Fakes is the successor, to Moles &amp; Stubs, and it rather elegantly solves the statics testability problem, by introducing the concept of <a href="https://docs.microsoft.com/en-us/visualstudio/test/isolating-code-under-test-with-microsoft-fakes?view=vs-2015&amp;redirectedfrom=MSDN">shims</a>.</p>
<p>But statics do have their uses, especially when we’re talking about hyper critical performance situations. For example static member access is approx. 5-6% faster than instance members. But more importantly <a href="https://en.wikipedia.org/wiki/Inversion_of_control" target="_blank" rel="noopener noreferrer">IOC</a> or <a href="https://en.wikipedia.org/wiki/Dependency_injection" target="_blank" rel="noopener noreferrer">Dependency Injection</a> itself are comparatively slow and frequently uses <a href="http://thargy.com/category/dev/reflection/" target="_blank" rel="noopener noreferrer">Reflection</a> (often inappropriately). For some scenarios, like logging, statics are powerful tool – if used with eyes wide open. To be clear, you can say that about pretty much any programming paradigm.</p>
<p>Back to the purpose of this post though. After trying to clear up a bit of the mud slung at statics (and at the risk of starting a flame war anywhere). Let’s talk about the greater evil of statics with <a href="https://en.wikipedia.org/wiki/Generic_programming#Genericity_in_.NET" target="_blank" rel="noopener noreferrer">generics</a>. These things are so <em>evil</em> that <a href="https://www.jetbrains.com:443/resharper/" target="_blank" rel="noopener noreferrer">ReSharper</a> (the tool you must install if you spend any time developing in .NET) gives you a nice little squiggle and warning &#8211;</p>
<p><a href="https://i0.wp.com/thargy.com/wp-content/uploads/2012/04/image.png"><img data-recalc-dims="1" loading="lazy" decoding="async" style="padding-left: 0px; padding-right: 0px; padding-top: 0px; border-width: 0px;" src="https://i0.wp.com/thargy.com/wp-content/uploads/2012/04/image_thumb.png?resize=340%2C222" alt="image" width="340" height="222" border="0" /></a></p>
<p>Clearly we’re talking about a great evil here!</p>
<p><a href="https://www.jetbrains.com:443/resharper/" target="_blank" rel="noopener noreferrer">ReSharper</a> is right to warn you about this as it’s a real issue for new developers to understand what’s going on. Going back to your old lectures – a <em>“Class is a definition of an object, and object is an instantiation of a class”</em>. In <a href="https://en.wikipedia.org/wiki/C_Sharp_(programming_language)" target="_blank" rel="noopener noreferrer">C#</a> you cannot instantiate a generic class, actually more accurately <em>you cannot instantiate an <strong>open</strong> generic class</em>. Now when you <a href="https://www.google.com/?gws_rd=ssl" target="_blank" rel="noopener noreferrer">Google</a> this be sure to use “open generic type” as that’s what everyone uses although in C# only classes and interfaces can be generic (a type describes pretty much every language element, including enums, structs, value types, delegates, generic arguments, etc.), and only classes can be instantiated (interfaces are implemented).</p>
<p>So what is an open generic class? It is a class where any of the generic arguments are not yet specified. The generic argument in our example is ‘T’ (as in Bag;).</p>
<p>To instantiate a generic class, you must first <em>close</em> it, that is fully specify it’s generic arguments. In code this is normally done when you instantiate it, e.g. {csharp decode=&#8221;true&#8221;}Bag&lt;T&gt; intBag = new Bag&lt;T&gt;();{/csharp}.  As you can see the we specify that the type T should in fact be of type ‘int’ for the ‘intBag’ instance of our generic Bag class. So what’s the problem? Well in closing a generic class you create a new type ‘Bag’ which is the closed generic class made from the ‘Bag’ open generic class, it is a <em>class</em> in it’s own right, and critically, <em>it has it’s own independent statics</em>. To the unwary this can appear counter intuitive, as they might expect that the static is shared across all instances of ‘Bag’ or it’s descendants, however Bag doesn’t have either and ‘Bag’ is not strictly a descendent.</p>
<p>So are all statics in generic types evil? Well let’s expand out our view a little &#8211;</p>
<p><a href="https://i0.wp.com/thargy.com/wp-content/uploads/2012/04/image1.png"><img data-recalc-dims="1" loading="lazy" decoding="async" style="padding-left: 0px; padding-right: 0px; padding-top: 0px; border-width: 0px;" src="https://i0.wp.com/thargy.com/wp-content/uploads/2012/04/image_thumb1.png?resize=581%2C262" alt="image" width="581" height="262" border="0" /></a></p>
<p>&#8211; for some reason <a href="https://www.jetbrains.com:443/resharper/" target="_blank" rel="noopener noreferrer">ReSharper</a> isn’t complaining about our new field ‘_thisIsOk’. The reason is simple, as the field itself is a generic and uses the generic argument of the encapsulating class it’s unlikely you are going to get confused over the field’s scope, unlike with ‘_bagCount’.</p>
<p>Should we just ban statics in generics and be done with it (easier said than done)? Well the answer to that is complex, but there are some really good examples of where it is very useful, some of which I’ll show you in future posts, the important thing is to remember that the static is only global to the closed generic type. In our example ‘_bagCount’ will only be global to ‘Bag’, a ‘Bag’ will have it’s own ‘_bagCount’ static. When you understand the limitation, you can also understand it’s usefulness.</p>
<p>Which brings us to the bit on which so many developers get stuck – <em>how do I have a static shared across all types of my generic class</em>? Well there are two ways really, the best way (if you ask me) is the base class model, for example &#8211;</p>
<pre class="lang:csharp mixed:false decode:true">public abstract class GenericBase
{
    protected static int _counter = 0;
}

public class Generic&lt;T&gt; : GenericBase
{
    public static int Counter { get { return _counter; } set { _counter = value; } }
}</pre>
<p>This is the most elegant solution, but a base class is not always a viable option (you may need to descend from a different class already. In that case you can use a holder class like so &#8211;</p>
<pre class="lang:csharp mixed:false decode:true">internal static class GenericHolder
{
    public static int Counter = 0;
}

public class Generic&lt;T&gt;
{
    public static int Counter { get { return GenericHolder.Counter; } set { GenericHolder.Counter = value; } }
}</pre>
<p>&#8211; which is far less elegant, although declaring the holder as internal at least means it’s not accessible outside the current assembly.</p>
<p>I plan on following up with far more in-depth examples, and apologise if this one is a little ‘basic’ but I wanted to get some groundwork done before I delve deeper into the .NET framework, and <a href="http://thargy.com/category/dev/reflection/" target="_blank" rel="noopener noreferrer">Reflection</a>.</p>
</div>
<h3>Related Images:</h3>
<p> [<a href="https://thargy.com/2012/04/statics-and-generics/">See image gallery at thargy.com</a>] </p>
]]></content:encoded>
					
					<wfw:commentRss>https://thargy.com/2012/04/statics-and-generics/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">89</post-id>	</item>
		<item>
		<title>Welcome</title>
		<link>https://thargy.com/2012/04/welcome/</link>
		
		<dc:creator><![CDATA[thargy]]></dc:creator>
		<pubDate>Mon, 09 Apr 2012 22:24:49 +0000</pubDate>
				<category><![CDATA[African Childrens' Choir]]></category>
		<category><![CDATA[Personal]]></category>
		<category><![CDATA[ACC]]></category>
		<category><![CDATA[Craig]]></category>
		<category><![CDATA[Uncle]]></category>
		<category><![CDATA[Welcome]]></category>
		<guid isPermaLink="false">http://thargy.com/?p=11</guid>

					<description><![CDATA[Hi everyone and welcome to the new thargy.com (and unclecraig.com). My old website was left untouched for 7 years and times have changed &#8211; as have I. For a start I&#8217;m posting this on my iPhone, which wasn&#8217;t even around when I stopped editing this site in earnest (around 2004). Most importantly I really want ...]]></description>
										<content:encoded><![CDATA[<div class="entry">
<p>Hi everyone and welcome to the new <a href="https://thargy.com/">thargy.com</a> (and <a href="https://thargy.com/">unclecraig.com</a>).</p>
<p>My old website was left untouched for 7 years and times have changed &#8211; as have I.  For a start I&#8217;m posting this on my iPhone, which wasn&#8217;t even around when I stopped editing this site in earnest (around 2004).</p>
<p>Most importantly I really want to start giving back to the community by open sourcing some of the exciting things we&#8217;ve been working on. And I have a head full of blogs I really need to write, so after much soul searching I&#8217;ve removed the old site (after backing it up first) and brought up this <a href="https://wordpress.org">WordPress</a> site.  After all, I want to focus on blogging not building a website.</p>
<p>Well I&#8217;ll keep this short.  I hope to convert my old newsletters into posts on hear, for nostalgia, and then maybe I&#8217;ll get round to that blog I&#8217;ve been meaning to write.</p>
<p>Thanks for visiting and leave a comment <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>Craig</p>
</div>
<h3>Related Images:</h3>
<p> [<a href="https://thargy.com/2012/04/welcome/">See image gallery at thargy.com</a>] </p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">11</post-id>	</item>
		<item>
		<title>Corporate Social Responsibility</title>
		<link>https://thargy.com/2012/02/corporate-social-responsibility/</link>
					<comments>https://thargy.com/2012/02/corporate-social-responsibility/#comments</comments>
		
		<dc:creator><![CDATA[thargy]]></dc:creator>
		<pubDate>Mon, 13 Feb 2012 16:03:00 +0000</pubDate>
				<category><![CDATA[Chamber of Commerce]]></category>
		<category><![CDATA[Management]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Corporate Social Responsibility]]></category>
		<category><![CDATA[CSR]]></category>
		<guid isPermaLink="false">http://thargy.com/?p=258</guid>

					<description><![CDATA[If you are a regular reader of my articles you will be aware that social responsibility is a key area I focus on. This policy needs to be addressed in order for any business, no matter what size to develop in the way it wants to. Without policies in place how can you determine where ...]]></description>
										<content:encoded><![CDATA[<div class="entry">
<p>If you are a regular reader of my articles you will be aware that social responsibility is a key area I focus on. This policy needs to be addressed in order for any business, no matter what size to develop in the way it wants to. Without policies in place how can you determine where your business is heading? </p>
<p><a href="https://www.groundwork.org.uk/" target="_blank" rel="noopener noreferrer">Groundwork</a>, a charity who specialise in environmental regeneration, have been hosting a range of workshops and seminars in order to educate local businesses. Recently they held a seminar on the topic of Corporate Social Responsibility. Timely, as <a href="https://www.apple.com/" target="_blank" rel="noopener noreferrer">Apple</a> have released sensitive information regarding their pollution and its origins. Although under pressure to do the right thing, Apple have said that they are working towards reducing their environmental impact – a response the public are eager to hear.  </p>
<p>Never has it been more important to factor Corporate Social Responsibility procedures into your company to establish core beliefs. A company’s beliefs need to be defined early in order to engage people who share similar views. This will be the message you advocate, therefore it has to be part of the fabric of the business. </p>
<p>Engage with local people, especially young people to encourage them to promote and prolong your message; you are preparing the next generation of workers. If you have no message in place you are allowing other people to fundamentally run your company rather than leading it yourself. </p>
<p>Give back to the community. The local community is vital to your business even if it is not a stakeholder. The image of the area can have a direct impact on your company as it represents you. As a result, creating positivity is a crucial step for your business.  </p>
<p>Work in partnership with other businesses. Together you can help others more effectively and in turn increase your workload when these efforts are reported. It’s not all about PR but in the ‘prove to me’ culture of our society you will need to recognise that what you do as a business is always being judged. </p>
<p>Considering Corporate Social Responsibility will enable you to make decisions regarding your company’s message. Primarily you will need to think about the differences you want to make, the differences you can make and the legacy you will leave. </p>
<p><a href="https://www.groundwork.org.uk/" target="_blank" rel="noopener noreferrer">Groundwork</a> are continuing to hold various events to give support to local businesses. For more details contact Jean Maxwell on 0161 624 1444 or e-mail <a href="mailto:jean.maxwell@groundwork.org.uk">jean.maxwell@groundwork.org.uk</a></p>
</div>
<h3>Related Images:</h3>
<p> [<a href="https://thargy.com/2012/02/corporate-social-responsibility/">See image gallery at thargy.com</a>] </p>
]]></content:encoded>
					
					<wfw:commentRss>https://thargy.com/2012/02/corporate-social-responsibility/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">258</post-id>	</item>
		<item>
		<title>The measure of Success</title>
		<link>https://thargy.com/2011/10/the-measure-of-success/</link>
					<comments>https://thargy.com/2011/10/the-measure-of-success/#comments</comments>
		
		<dc:creator><![CDATA[thargy]]></dc:creator>
		<pubDate>Wed, 26 Oct 2011 15:39:00 +0000</pubDate>
				<category><![CDATA[Chamber of Commerce]]></category>
		<category><![CDATA[Management]]></category>
		<category><![CDATA[Education]]></category>
		<category><![CDATA[Korzybski]]></category>
		<category><![CDATA[Profit]]></category>
		<category><![CDATA[Sanity]]></category>
		<category><![CDATA[Success]]></category>
		<category><![CDATA[Turnover]]></category>
		<guid isPermaLink="false">http://thargy.com/?p=240</guid>

					<description><![CDATA[How do you measure success? In the business world there’s a misplaced obsession with two metrics – turnover and profit.&#160; Running your business within these parameters would be like choosing your life partner based only on eye colour and height &#8211; I suppose it’s a start, but you would be missing out on so much ...]]></description>
										<content:encoded><![CDATA[<div class="entry">
<p><a href="https://i0.wp.com/thargy.com/wp-content/uploads/2012/05/alfred-korzybski.b.jpg"><img data-recalc-dims="1" loading="lazy" decoding="async" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top: 0px; border-right: 0px; padding-top: 0px" title="alfred-korzybski.b" border="0" alt="alfred-korzybski.b" align="right" src="https://i0.wp.com/thargy.com/wp-content/uploads/2012/05/alfred-korzybski.b_thumb.jpg?resize=216%2C244" width="216" height="244"></a>How do you measure success? In the business world there’s a misplaced obsession with two metrics – turnover and profit.&nbsp; Running your business within these parameters would be like choosing your life partner based only on eye colour and height &#8211; I suppose it’s a start, but you would be missing out on so much else. </p>
<p>You will have heard of the adage “turnover is vanity, profit is sanity”.&nbsp; I hate that phrase. Half of the message isn’t bad – turnover is indeed<i> </i>vanity; one guy in a bedroom reselling second hand planes can turnover £16m from one sale of an Airbus A340-500, which is no indicator of the profit he’ll make.&nbsp; But profit is anything but sanity – a bit like oxygen, it satisfies our immediate survival, but in the long run we’ll need more if we want to prosper, such as food and water. </p>
<p><a href="https://en.wikipedia.org/wiki/Alfred_Korzybski" target="_blank" rel="noopener noreferrer">Alfred Korzybski</a> argued that sanity was tied to the structural fit between our reactions to the world and what is actually happening in the world.&nbsp; A sane business is not detached from its surroundings, it is embedded in them.&nbsp; A sane business is concerned with its impact in its own industry, in its community, on its employees. It would be corporate insanity to run a business solely with the aim of making a profit. A perfect example of this can be seen in the recent financial crisis, when some banks became so obsessed with their profits that they failed to monitor the very foundations from which those profits had come. </p>
<p>There are great moral and philanthropic reasons for getting involved in your local community, sponsoring local causes and donating your resources for fundraising purposes. The success of your community reflects your success and vice versa – you need each other to survive. </p>
<p>However, there are also indisputable business incentives for getting involved in local ventures. Speaking from experience, businesses who get involved in projects that will benefit the community are rewarded with valuable knowledge of their locality, knowledge of their marketplace and access to an ancient but indispensable marketing tool: word of mouth.  </p>
<p>There are other ways we can become involved in our local community. My personal passion is education – I believe the more opportunities we can offer local young people, the more we are able to offer Oldham’s future business community. If you agree with this sentiment, then have your say – there are many chances to sit on the boards of local educational institutions. If you are more concerned with Oldham’s current business climate, contact the Oldham branch of the <a href="https://www.gmchamber.co.uk/" target="_blank" rel="noopener noreferrer">Greater Manchester Chamber of Commerce</a>, who can make a real difference to today’s business practices. </p>
<p>Success is not founded on what a business can take, but on what a business can give. “Turnover is vanity, impact is sanity – profit is the result”. It may not be as catchy, but it is a far more realistic measure of business success.</p>
</div>
<h3>Related Images:</h3>
<p> [<a href="https://thargy.com/2011/10/the-measure-of-success/">See image gallery at thargy.com</a>] </p>
]]></content:encoded>
					
					<wfw:commentRss>https://thargy.com/2011/10/the-measure-of-success/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">240</post-id>	</item>
		<item>
		<title>Legacy</title>
		<link>https://thargy.com/2011/09/legacy/</link>
		
		<dc:creator><![CDATA[thargy]]></dc:creator>
		<pubDate>Thu, 08 Sep 2011 15:29:00 +0000</pubDate>
				<category><![CDATA[Chamber of Commerce]]></category>
		<category><![CDATA[Management]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[DOS]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Legacy]]></category>
		<category><![CDATA[Microsoft]]></category>
		<guid isPermaLink="false">http://thargy.com/?p=236</guid>

					<description><![CDATA[Legacy. At times it can be a boon, inspiring culture and rooting us with a strong identity forged in the fires of history. But it can also be a weighty anchor pulling us to the bottom. In business, there are no awards for being first out of the blocks; the gold medals are reserved for ...]]></description>
										<content:encoded><![CDATA[<div class="entry">
<p>Legacy. At times it can be a boon, inspiring culture and rooting us with a strong identity forged in the fires of history. But it can also be a weighty anchor pulling us to the bottom. In business, there are no awards for being first out of the blocks; the gold medals are reserved for those first past the finish line. </p>
<p>This can be seen in the battle between <a href="https://www.microsoft.com/en-us/" target="_blank" rel="noopener noreferrer">Microsoft</a> and <a href="https://www.apple.com/" target="_blank" rel="noopener noreferrer">Apple</a>. <a href="https://en.wikipedia.org/wiki/Steve_Jobs" target="_blank" rel="noopener noreferrer">Steve Jobs</a> rebuilt <a href="https://www.apple.com/" target="_blank" rel="noopener noreferrer">Apple</a> from a company facing imminent implosion into (for a brief period this summer) the most valuable company in the world (it’s currently second behind Exxon Mobil). Famously, he did so by simplifying and cutting features &#8211; Jobs was the first to drop the floppy disk drive, the removable battery and now the CD/DVD. The original iPhone lacked the majority of features (such as cut and paste) that competitors believed to be essential. This freedom from past conventions allowed <a href="https://www.apple.com/" target="_blank" rel="noopener noreferrer">Apple</a> to flourish and grow. </p>
<p>While <a href="https://www.apple.com/" target="_blank" rel="noopener noreferrer">Apple</a> steams ahead with innovative ideas, <a href="https://www.microsoft.com/en-us/" target="_blank" rel="noopener noreferrer">Microsoft</a> continues to utilise its <a href="https://en.wikipedia.org/wiki/DOS" target="_blank" rel="noopener noreferrer">DOS</a> features of the past, such as the command prompt, even though <a href="https://en.wikipedia.org/wiki/DOS" target="_blank" rel="noopener noreferrer">MS-DOS</a> reached 30 years of age in July – practically an antique in IT terms. Last week, <a href="https://www.microsoft.com/en-us/" target="_blank" rel="noopener noreferrer">Microsoft</a> demonstrated its planned changes to Windows Explorer for <a href="https://support.microsoft.com/hub/4338813/windows-help" target="_blank" rel="noopener noreferrer">Windows 8</a>, while <a href="https://www.apple.com/" target="_blank" rel="noopener noreferrer">Apple</a> continued to question why we need a file explorer at all. Is <a href="https://www.microsoft.com/en-us/" target="_blank" rel="noopener noreferrer">Microsoft</a>’s legacy also its limit? </p>
<p>We can liken this scenario to telecoms. It is effectively impossible to purchase an Internet connection without the obligatory landline, although landlines are used less and less, because the technology is becoming redundant. In developing countries, the development of cell phones has allowed users to gain ubiquitous connectivity in less than a decade, skipping an entire generation of infrastructure development. </p>
<p>With the tech world abuzz over India’s plans to spend tens of billions to expand its broadband network, there’s no doubt that the world is waking up to the power of connectivity to drive growth and development. In the UK, we have a huge network of dated copper and aluminium wiring that telcos (telecommunications companies) are still desperate to monetize. But our future legacy is not about metal and electricity, it’s about fibre and light. With current technology, fibre can already carry thousands of times more information than copper. The UK is already starting to lag behind our Western counterparts in fibre infrastructure, and there’s a lot of confusion amongst policy-makers, who are easily bamboozled by telcos with complex agendas. </p>
<p>Oldham’s council appear to have grasped the importance of being at the vanguard of fibre rollout and are campaigning to bring fibre down the tram lines to our borough. This is a laudable statement of intent and has huge potential to promote local growth. Of course, intent is only the first step on the road to delivery and there’s a lot of work to do still. While we may be out of the starting blocks, the finish line remains a long way off.</p>
</div>
<h3>Related Images:</h3>
<p> [<a href="https://thargy.com/2011/09/legacy/">See image gallery at thargy.com</a>] </p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">236</post-id>	</item>
		<item>
		<title>History</title>
		<link>https://thargy.com/2011/07/history/</link>
		
		<dc:creator><![CDATA[thargy]]></dc:creator>
		<pubDate>Wed, 13 Jul 2011 15:51:00 +0000</pubDate>
				<category><![CDATA[Chamber of Commerce]]></category>
		<category><![CDATA[Management]]></category>
		<category><![CDATA[Action for business]]></category>
		<category><![CDATA[Aged Debt]]></category>
		<category><![CDATA[Debbie Abrahams]]></category>
		<category><![CDATA[GMCC]]></category>
		<category><![CDATA[History]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[Late Payment]]></category>
		<guid isPermaLink="false">http://thargy.com/?p=252</guid>

					<description><![CDATA[After more than two centuries it is probably a good time to ask, ‘Is the Chamber of Commerce still relevant?’ Businessmen in the last decade of the 18th Century were hardly worried about developing an effective social media strategy, or obsessing how their website would look viewed on an iPad. How could a Chamber founded ...]]></description>
										<content:encoded><![CDATA[<div class="entry">
<p><a href="https://i0.wp.com/thargy.com/wp-content/uploads/2012/05/man-of-fashion_fashionable-male.jpg"><img data-recalc-dims="1" loading="lazy" decoding="async" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top: 0px; border-right: 0px; padding-top: 0px" title="man-of-fashion_fashionable-male" border="0" alt="man-of-fashion_fashionable-male" align="left" src="https://i0.wp.com/thargy.com/wp-content/uploads/2012/05/man-of-fashion_fashionable-male_thumb.jpg?resize=197%2C244" width="197" height="244"></a>After more than two centuries it is probably a good time to ask, ‘Is the Chamber of Commerce still relevant?’ Businessmen in the last decade of the 18<sup>th</sup> Century were hardly worried about developing an effective social media strategy, or obsessing how their website would look viewed on an <a title="The new iPad" href="https://www.apple.com/uk/ipad/" target="_blank" rel="noopener noreferrer">iPad</a>. How could a Chamber founded practically in the dark ages still have value to businesses today? By staying in touch with the ever changing and evolving issues of its members and the outer community. </p>
<p>When I joined the chamber a couple of years ago I expected to find a group of dotty old men in smoking jackets reminiscing about the good old days. What I found was a passionate cohort of motivated men and women who not only recognised the need for change, in themselves and in business, but also believed in their ability to instigate change. </p>
<p>That drive and focus has led to ‘Action for Business’ a distilled set of policy priorities broken down into six key areas, and a template for focusing the Chambers efforts to ensure a fairer deal for business and our economy. It is an impressive document and I highly recommend reading it (it can be found on the home page of the Chamber’s website at <a href="https://www.gmchamber.co.uk/">www.gmchamber.co.uk</a>). But it isn’t just an exercise in generating paperwork; it genuinely infuses what the modern Chamber is about – Action. Action found in campaigning for change, better infrastructure and fairness; promoting positive policies, incentives and opportunities; and calling for new approaches, new attitudes and new R&amp;D. </p>
<p>One policy the document highlights is the need to raise awareness of the impact late payments has on business. Debbie Abraham, our newest MP, recently launched her own campaign on this issue called ‘Be Fair Pay On Time’ in an attempt to highlight the injustice of late payments, you have possibly seen it recently highlighted in this newspaper. You can join Debbie’s campaign on Facebook, or via her website at <a href="https://debbieabrahams.org.uk/">www.debbieabrahams.org.uk</a>. </p>
<p>Late payment is an abhorrent practice, and I would love to see the government adopt a policy of self-reporting – where companies report their own late payments in their published accounts, in the same way businesses self-report on tax liability. Such an approach would break the pattern of asking suppliers to police late payments, normally to the detriment of their own business as customers seek more pliant suppliers elsewhere. I welcome Debbie’s and the Chamber’s willingness to take a stance on the issue.  </p>
<p>Ironically one of the earliest minutes, of the Commercial Society (the pre-cursor to the Chamber in Manchester) listed three key objectives the second of which was ‘…the regulation of trade, including the promotion of regular payments’. </p>
<p>Clearly the Chamber is just as relevant today.</p>
</div>
<h3>Related Images:</h3>
<p> [<a href="https://thargy.com/2011/07/history/">See image gallery at thargy.com</a>] </p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">252</post-id>	</item>
		<item>
		<title>Bolton Lads &#038; Girls Club</title>
		<link>https://thargy.com/2011/06/bolton-lads-girls-club/</link>
		
		<dc:creator><![CDATA[thargy]]></dc:creator>
		<pubDate>Wed, 08 Jun 2011 15:48:00 +0000</pubDate>
				<category><![CDATA[Chamber of Commerce]]></category>
		<category><![CDATA[Management]]></category>
		<category><![CDATA[BLGC]]></category>
		<category><![CDATA[Mahdlo]]></category>
		<guid isPermaLink="false">http://thargy.com/?p=248</guid>

					<description><![CDATA[Last night I found myself at the Bolton Lads &#38; Girls Club. I had been invited for a tour of the facility by Claire Crossfield who is part of the team building a new youth zone facility in the heart of Oldham. The local young people have been very involved in this new centre’s progress ...]]></description>
										<content:encoded><![CDATA[<div class="entry">
<p><a href="https://i0.wp.com/thargy.com/wp-content/uploads/2012/05/MAHDLO-logo.png"><img data-recalc-dims="1" loading="lazy" decoding="async" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top: 0px; border-right: 0px; padding-top: 0px" title="MAHDLO-logo" border="0" alt="MAHDLO-logo" align="right" src="https://i0.wp.com/thargy.com/wp-content/uploads/2012/05/MAHDLO-logo_thumb.png?resize=120%2C159" width="120" height="159"></a>Last night I found myself at the <a href="https://boltonladsandgirlsclub.co.uk/" target="_blank" rel="noopener noreferrer">Bolton Lads &amp; Girls Club</a>. I had been invited for a tour of the facility by Claire Crossfield who is part of the team building a new youth zone facility in the heart of Oldham. The local young people have been very involved in this new centre’s progress and have named it <a href="https://www.mahdloyz.org/" target="_blank" rel="noopener noreferrer">Mahdlo</a> (Oldham backwards). <a href="https://www.mahdloyz.org/" target="_blank" rel="noopener noreferrer">Mahdlo</a> is based on the work pioneered by the Bolton Lads &amp; Girls Club, and aims to create a central place where young people can meet and thrive. </p>
<p>Having just received another depressing report on my desk regarding the economic prospects for the borough, it might seem strange that I want to talk about <a href="https://www.mahdloyz.org/" target="_blank" rel="noopener noreferrer">Mahdlo</a>, but I cannot think of anything more important. <a href="https://www.mahdloyz.org/" target="_blank" rel="noopener noreferrer">Mahdlo</a> is a great example of what I wrote about in my last column – an opportunity for the Oldham business community to invest in the long term future economic prospects of the borough. </p>
<p>And I do mean opportunity. I am not blind to the difficulties faced by our businesses, indeed they can often be summed up in one word – ‘cash’; but not all investment is financial. <a href="https://www.mahdloyz.org/" target="_blank" rel="noopener noreferrer">Mahdlo</a> presents a real opportunity for staff development as you encourage your staff to take part in volunteering as mentors and supporters of the many activities that are planned to be on offer. <a href="https://www.mahdloyz.org/" target="_blank" rel="noopener noreferrer">Mahdlo</a> is currently planning on signing up volunteers to help with youth work, arts, sports and mentoring. </p>
<p>There is a real chance here for improving recruitment as you promote career choices through job clubs and offer apprenticeships and internships, as well as improving attainment through homework clubs and improved facilities for schools. <a href="https://www.mahdloyz.org/" target="_blank" rel="noopener noreferrer">Mahdlo</a> also encourages staff retention as working parents can take advantage of the holiday clubs on offer which will look after children during school holidays – giving them structured activities in a safe environment for ridiculously low costs. </p>
<p>There is scope for town centre renovation as we engage young people more effectively and attract more people to the borough – some youths travel to Bolton regularly from as far afield as Liverpool to attend the club there. </p>
<p>As building moves on a pace, with the opening scheduled for the end of this year; this has to be one of the more attractive opportunities for local businesses to be getting involved in. I encourage you to get hold of Claire and start investing in your future. </p>
<p>Get in touch with Claire from On Side Northwest about available opportunities at: <a href="mailto:claire.crossfield@onsidenorthwest.org">claire.crossfield@onsidenorthwest.org</a></p>
</div>
<h3>Related Images:</h3>
<p> [<a href="https://thargy.com/2011/06/bolton-lads-girls-club/">See image gallery at thargy.com</a>] </p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">248</post-id>	</item>
		<item>
		<title>Presidential announcements</title>
		<link>https://thargy.com/2011/05/presidential-announcements/</link>
		
		<dc:creator><![CDATA[thargy]]></dc:creator>
		<pubDate>Mon, 09 May 2011 15:43:00 +0000</pubDate>
				<category><![CDATA[Chamber of Commerce]]></category>
		<category><![CDATA[Management]]></category>
		<category><![CDATA[GMCC]]></category>
		<category><![CDATA[Oldham]]></category>
		<category><![CDATA[President]]></category>
		<guid isPermaLink="false">http://thargy.com/?p=244</guid>

					<description><![CDATA[Craig Dean is the new Oldham President of Greater Manchester Chamber of Commerce and Chief Executive of Web Applications UK. The Oldham business community is a dynamic, thriving and overwhelmingly positive group of people which is unquestionably surprising to ‘outsiders’ considering the ceaseless tirade of negative punditry that surrounds the prospects for our economy and ...]]></description>
										<content:encoded><![CDATA[<div class="entry">
<p><a href="https://i0.wp.com/thargy.com/wp-content/uploads/2012/05/clip_image002.jpg"><img data-recalc-dims="1" loading="lazy" decoding="async" style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px 8px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top: 0px; border-right: 0px; padding-top: 0px" title="clip_image002" border="0" alt="clip_image002" align="left" src="https://i0.wp.com/thargy.com/wp-content/uploads/2012/05/clip_image002_thumb.jpg?resize=209%2C183" width="209" height="183"></a> </p>
<p><b>Craig Dean is the new Oldham President of Greater Manchester Chamber of Commerce and Chief Executive of Web Applications UK. </b> </p>
<p>The Oldham business community is a dynamic, thriving and overwhelmingly positive group of people which is unquestionably surprising to ‘outsiders’ considering the ceaseless tirade of negative punditry that surrounds the prospects for our economy and business in general.&nbsp; As an Oldhamer, I am not surprised though. We are a well-watered bunch, which only serves to let us appreciate the few fantastically sunny days (like we have just experienced) all the more.&nbsp; </p>
<p>Paul Roberts, my presidential predecessor, is the perfect embodiment of hard work and it is a little intimidating to be taking over as President in Oldham, but I am excited by what lies ahead. It is not just the anticipation of facing up to a challenging economy that I find exciting; it is that we have a plan.&nbsp; Oldham as a council, and a community, is focused on the future in the truest sense – by being focused on education.&nbsp; As a business community we are beginning to reap the benefits of this strategy already as we witness the next generation of employees and employers, graduates from our schools, our colleges and now our university. </p>
<p>Hard times see cuts, and there is a short-sighted temptation for businesses to ignore staff development as programmes such as ‘train to gain’ come under the axe.&nbsp; We should not forget our heritage or underestimate the impact of under-investing in education on our future and our success. It was the business community that first founded the schools and fought to educate their staff and their children, and it is the business community that can inspire and lead the education revolution of the future. <a name="_GoBack"></a> </p>
<p>As President, it is my desire to see businesses re-engage in education in a powerful and positive way, and there is no better time to start getting involved.&nbsp; Our excellent new academies are literally open for business, and never before have we been given such an opportunity to shape and influence the education landscape.&nbsp; Apprenticeships have a sharp new focus as we move them back to a place where they are considered a legitimate pathway to employment and adult education is providing legitimate benefits to employees and their employers alike. </p>
<p>A strategy that is founded on having the best and the brightest is a strategy that the business community can and should get fully behind. With such a clear strategy there is reason to be positive. </p>
<p>If there are any members from any sector within the Oldham borough who are finding that their business operations are being impacted by certain issues, or you are interested in joining Greater Manchester Chamber of Commerce, please contact Michelle Geoghegan, our Oldham Local Policy Manager, at <a href="mailto:michelle.geoghegan@gmchamber.co.uk">michelle.geoghegan@gmchamber.co.uk</a>.  </p>
<p><b></b> </p>
<p><a href="https://www.gmchamber.co.uk/">www.gmchamber.co.uk</a> <a href="https://www.koder.ly/">www.webapplicationsuk.com</a></p>
</div>
<h3>Related Images:</h3>
<p> [<a href="https://thargy.com/2011/05/presidential-announcements/">See image gallery at thargy.com</a>] </p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">244</post-id>	</item>
		<item>
		<title>Innovation has a human face &#8211; tech is just a tool</title>
		<link>https://thargy.com/2011/03/innovation-has-a-human-face-tech-is-just-a-tool/</link>
					<comments>https://thargy.com/2011/03/innovation-has-a-human-face-tech-is-just-a-tool/#comments</comments>
		
		<dc:creator><![CDATA[thargy]]></dc:creator>
		<pubDate>Wed, 16 Mar 2011 06:00:00 +0000</pubDate>
				<category><![CDATA[Innovation]]></category>
		<category><![CDATA[Management]]></category>
		<guid isPermaLink="false">http://thargy.com/?p=262</guid>

					<description><![CDATA[This article first appeared as a guest post in Travolution. If you want to move forward, steer clear of protectionism and build a culture of knowledge-sharing, says Web Applications chief executive Craig Dean Such has been the pace of technological advancement in our lifetime that the word innovation seems to have become synonymous with technology. ...]]></description>
										<content:encoded><![CDATA[<div class="entry">
<p><em><a href="http://www.travolution.com/articles/4474/opinion-innovation-has-a-human-face---tech-is-just-a-tool" target="_blank" rel="noopener noreferrer">This article first appeared as a guest post in Travolution.</a></em> </p>
<p><strong>If you want to move forward, steer clear of protectionism and build a culture of knowledge-sharing, says </strong><a href="https://www.koder.ly/"><strong>Web Applications</strong></a><strong> chief executive Craig Dean</strong> </p>
<p><img decoding="async" style="display: inline; float: left" border="0" alt="Web Applications chief executive Craig Dean" align="left" src="http://www.travolution.com/articles/2011/03/16/assets/getAsset.aspx?ItemID=2812">Such has been the pace of technological advancement in our lifetime that the word innovation seems to have become synonymous with technology. </p>
<p>Sitting in my office in a converted mill in the heart of the industrial north, I find myself reflecting on innovation constantly. I am reminded that the origins of the word span back not just to the start of the internet age, or the age of the transistor, but way back, past the dawn of the industrial revolution and into the Middle Ages, at least. </p>
<p>When people talk about innovation they associate it with something new, and that is an easy mistake to make. The word itself descends from the Latin ‘innovare’, which is itself formed from ‘novus’ which gives us the word ‘new’. However, an accurate translation is ‘to renew or change’. </p>
<p>My dull fascination with etymology aside, I can’t think of a more vital point on which to focus – innovation is about change. </p>
<p>As a technology provider, it is easy to think that I would subscribe to the notion that the route to success is buying a new system. Don’t get me wrong; if you’re in the market I will happily sell you one! However, when I talk to new customers the first thing I say to them is that purchasing a system is actually the easy bit – changing their business is where the project will really succeed, or fail. </p>
<p>When I say changing their business, I am really starting to talk about the way their people not only work, but the way they think. Innovation is all about adaptability, and adaptability is all about the kind of people you employ. When we recruit, we do not test for what people already know, in our industry that would be a losing battle as what they know will be of little value in a couple more years. </p>
<p>Instead, we look for a desire to grow, to learn, and most importantly, to change. It’s a running joke in our office that you should look before you sit down in case someone has been moved into your seat; we never let people get too comfortable with the status quo. </p>
<p>In technology it is easy for people to develop a silo mentality, specialising to the point of protectionism. It is a natural temptation to jealously guard our hard-won solutions, to establish dominance in our chosen field. </p>
<p>That kind of protectionism is the enemy of change and is counterproductive not only for the business, but for the individual, who finds himself typecast and ultimately side-lined. Everyone knows a colleague who is the only one that knows how to do that critical process. Rooting them out is the first step to creating a positive culture for change. </p>
<p>Instead, it is important to create an environment of constant learning and constant teaching – or knowledge sharing. When people are placed in boxes they stop innovating, when they are set free to teach others they solidify their own understanding and develop a desire to learn more themselves. </p>
<p>So technology is not innovation, it is just a tool; used correctly it frees up people to work smarter, and allows them to change. Technology does not drive innovation, people do.</p>
</div>
<h3>Related Images:</h3>
]]></content:encoded>
					
					<wfw:commentRss>https://thargy.com/2011/03/innovation-has-a-human-face-tech-is-just-a-tool/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">262</post-id>	</item>
	</channel>
</rss>
