<?xml version="1.0" encoding="UTF-8"?><!-- generator="wordpress.com" -->
<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/"
	>

<channel>
	<title>internals &amp;laquo; WordPress.com Tag Feed</title>
	<link>http://en.wordpress.com/tag/internals/</link>
	<description>Feed of posts on WordPress.com tagged "internals"</description>
	<pubDate>Sun, 29 Nov 2009 01:56:31 +0000</pubDate>

	<generator>http://en.wordpress.com/tags/</generator>
	<language>en</language>

<item>
<title><![CDATA[Why is SQL Azure and Index Fragmentation a Bad Combination?]]></title>
<link>http://sqlfascination.com/2009/11/25/why-is-sql-azure-and-index-fragmentation-a-bad-combination/</link>
<pubDate>Wed, 25 Nov 2009 22:20:10 +0000</pubDate>
<dc:creator>andrewhogg</dc:creator>
<guid>http://sqlfascination.com/2009/11/25/why-is-sql-azure-and-index-fragmentation-a-bad-combination/</guid>
<description><![CDATA[I&#8217;ve been thinking through and experimenting a bit more with some of the concepts in SQL Azure]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>I&#8217;ve been thinking through and experimenting a bit more with some of the concepts in SQL Azure &#8211; specifically I was considering the impact of fragmentation on both the storage (in terms of the storage limit) as well as the maintenance. This is not a new issue, DBA&#8217;s face fragmentation regularly and can deal with it in a variety of ways, but with SQL Azure the problem looks magnified by a lack of tools and working space. Whilst looking into this, I then realised that there is an unfortunate consequence of not knowing how much data space your index is actually using.</p>
<p>Each table in SQL Azure has to have a clustered index if data is going to be inserted into it and clustered indexes can suffer from fragmentation if chosen poorly. The combination of SQL Azure and the time-honoured fragmentation provides three consequences about in, fragmentation:</p>
<ul>
<li>will occur and you have no way in which to measure it due to the lack of DMV support.</li>
<li>will create wasted space within your space allocation limit.</li>
<li>will reduce your performance.</li>
</ul>
<p>You could work it out if you knew how much space you had actually used vs. what the size of the data held is, but we are unable to measure either of those values. If you have chosen the data compression option on the index then even those values would not give you a fragmentation ratio.</p>
<p>This leaves us with a situation in which you can not know how much you are fragmented, meaning:</p>
<ul>
<li>You schedule a regular index rebuild.</li>
<li>Hope SQL Azure performs index rebuilds for you.</li>
</ul>
<p>I&#8217;m not aware of SQL Azure doing this for you &#8211; and you do not have SQL Agent facilities either.</p>
<p>So this seems very wrong, the concept of SQL Azure is to take away a lot of the implementation details and hassle from the subscriber &#8211; DR and failover is handled etc. But there looks to be as gap in which certain items such as fragmentation is falling &#8211; I have not seen any documentation saying SQL Azure handles it (but there could be some hidden somewhere and I hope there is!) and neither are you given the right tools in which to program and handle it yourself.</p>
<p>What happens when you hit that size limit?</p>
<pre><span style="color:#ff0000;">Msg 40544, Level 20, State 5, Line 1 The database has reached its size quota. Partition or delete data, drop indexes, or consult the documentation for possible resolutions. Code: 524289 </span></pre>
<p>That took a lot of time to get to, (SQL Azure is not fast), but was generated using a simple example that would also demonstrate fragmentation.</p>
<pre><span style="color:#0000ff;">Create Table</span> fragtest ( id <span style="color:#0000ff;">uniqueidentifier primary key clustered</span>,
padding <span style="color:#0000ff;">char</span>(3000)
) </pre>
<p>Very simple stuff, deliberately using a clustered key on a GUID to cause a decent level of fragmentation, and also using the padding fixed with character field to ensure 2 rows per page only, maximising the page splits.</p>
<pre><span style="color:#0000ff;">insert into</span> fragtest <span style="color:#0000ff;">values</span> (<span style="color:#ff00ff;">newid</span>(), <span style="color:#ff00ff;">replicate</span>(<span style="color:#ff0000;">'a'</span>,1000))
go 200000</pre>
<p>Because of the randomness of the newid() function, the level of fragmentation is not predictable but will certainly occur &#8211; in my test I hit the wall on 196,403 records and failed with an out of space message.</p>
<p>Given the 2 rows per page and the number of rows, with ~0% fragmentation the data should be able ~767Mb &#8211; that is considerably short of 1 Gb &#8211; so there is a significant level of fragmentation in there wasting space, about 23% of it. If you include the 2k per page being wasted by the awkward row size then the actual raw data stored is roughly ~60% of the overall size allowing for row overheads etc.</p>
<p>So there are two important points from this contrived example:</p>
<ul>
<li>You can lose significant space from bad design.</li>
<li>Doing this backs you into a corner that you will not be able to get out of &#8211; this is the worst part.</li>
</ul>
<p>How are you cornered? well, try work out how to get out of the situation and defrag the clustered index / free up the space, you could:</p>
<ul>
<li>Attempt an index rebuild.</li>
<li>Try to rebuild it with SORT_IN_TEMP.</li>
<li>Drop the index.</li>
<li>Delete data.</li>
</ul>
<p>The first three fail, the SORT_IN_TEMP is not supported and would not of rescued the situation either since you have no working space in which to write the newly sorted rows prior to removing the old ones.  So do you really want to delete data? I don&#8217;t think we can consider that an option for now.</p>
<p>This all seems like a &#8216;rock&#8217; and a &#8216;hard place&#8217;; whilst SQL Azure can support these data quantities,  it seems prudent that you never consider actually going close to them at all &#8211; and that you equally are going to find it difficult to understand if you are close to them, since there is no way of measuring the fragmentation. The alternative is that you manually rebuild indexes on a regular basis to control fragmentation, but then enough free space is going to have to be left to allow you to rebuild your largest index without running out of space &#8211; reducing your data capacity significantly.</p>
<p>The corner is not entirely closed off, the way out of the corner would be to create another SQL Azure database within my account and select the data from database1.fragtest to database2.fragtest and then drop the original table and transfer it back &#8211; not ideal but it would work in an emergency.</p>
<p>I think the key is to design to make sure you do not have to face this issue; keep your data quantities very much under the SQL Azure size limits, and watch for the potential of tables being larger than the remaining space and preventing an re-indexing from occurring.</p>
<p>Interested to know your thoughts on this one, and what other consequences of being close to the limit will come out.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Troubleshooting #PowerPivot Excel Services connectivity]]></title>
<link>http://powerpivottwins.com/2009/11/18/troubleshooting-powerpivot-excel-services-connectivity/</link>
<pubDate>Wed, 18 Nov 2009 04:07:58 +0000</pubDate>
<dc:creator>dennyglee</dc:creator>
<guid>http://powerpivottwins.com/2009/11/18/troubleshooting-powerpivot-excel-services-connectivity/</guid>
<description><![CDATA[You’re on your way to PowerPivot for SharePoint functionality – you’ve uploaded your PowerPivot for ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>You’re on your way to PowerPivot for SharePoint functionality – you’ve uploaded your PowerPivot for Excel workbook to your SharePoint PowerPivot Gallery.  You view the thumbnails of your report and they look nice.</p>
<p><a href="http://dennyglee.files.wordpress.com/2009/11/image.png"><img title="image" src="http://dennyglee.files.wordpress.com/2009/11/image_thumb.png?w=370&#038;h=167#38;h=167" border="0" alt="image" width="370" height="167" /></a></p>
<p>&#160;</p>
<p>From the thumbnail, you click on the report you want to see, and the report renders nicely.</p>
<p><a href="http://dennyglee.files.wordpress.com/2009/11/image1.png"><img title="image" src="http://dennyglee.files.wordpress.com/2009/11/image_thumb1.png?w=354&#038;h=178#38;h=178" border="0" alt="image" width="354" height="178" /></a></p>
<p>&#160;</p>
<p>But then you click on a slicer, and then all of a sudden you get an error like the one below.</p>
<p><a href="http://dennyglee.files.wordpress.com/2009/11/image2.png"><img title="image" src="http://dennyglee.files.wordpress.com/2009/11/image_thumb2.png?w=260&#038;h=191#38;h=191" border="0" alt="image" width="260" height="191" /></a></p>
<p> What can you do? </p>
<p><a href="http://dennyglee.com/2009/11/18/troubleshooting-powerpivot-excel-services-connectivity/">Read more&#8230;</a></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Steps taken during a #PowerPivot data refresh]]></title>
<link>http://powerpivottwins.com/2009/11/18/steps-taken-during-a-powerpivot-data-refresh/</link>
<pubDate>Wed, 18 Nov 2009 03:35:27 +0000</pubDate>
<dc:creator>dennyglee</dc:creator>
<guid>http://powerpivottwins.com/2009/11/18/steps-taken-during-a-powerpivot-data-refresh/</guid>
<description><![CDATA[In this posting we will take a more detailed technical look at how the data refresh facility works a]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>In this posting we will take a more detailed technical look at how the data refresh facility works and the steps that it takes to accomplish a data refresh cycle. Rather than starting with the “Manage data refresh” page, we will assume that you know how to setup a schedule – in this posting, we will take a deep dive into the cycle itself.</p>
<h4>What steps are taken when the data is refreshed?</h4>
<p>Now that you have configured your schedule(s) for the workbook, let’s take a step back and examine more closely what data refresh actually means. I think that it is valuable to understand, at some basic level, exactly what the system is going to do on your behalf at 2am in the morning. When a job actually run, the data refresh facility goes through the following steps:</p>
<p><a href="http://powerpivotgeek.com/2009/11/12/steps-taken-during-a-powerpivot-data-refresh/">Read more&#8230;</a></p>
<p>&#160;</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[A Peek Inside #PowerPivot: The client architecture]]></title>
<link>http://powerpivottwins.com/2009/11/18/a-peek-inside-powerpivot-the-client-architecture/</link>
<pubDate>Wed, 18 Nov 2009 03:24:50 +0000</pubDate>
<dc:creator>dennyglee</dc:creator>
<guid>http://powerpivottwins.com/2009/11/18/a-peek-inside-powerpivot-the-client-architecture/</guid>
<description><![CDATA[Well, I have a fun one today. We get asked all of the time about how the PowerPivot add-in works. Pa]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Well, I have a fun one today. We get asked all of the time about how the PowerPivot add-in works. Particularly how it relates to the SSAS components that BI Pros are used to, e.g. making connections to SSAS. As I am getting ready to write an architecture overview blog posting for the PowerPivot team blog, I decided to take the client architecture out for a spin and attempt a more detailed drilldown here . . .</p>
<p>Here is a block diagram of the PowerPivot client component architecture</p>
<p><a href="http://powerpivotgeek.com/2009/11/11/a-peek-inside-the-client-architecture/">Read More&#8230;</a></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[BLEVEL and Height of Indexes]]></title>
<link>http://mwidlake.wordpress.com/2009/11/13/blevel-and-height-of-indexes/</link>
<pubDate>Fri, 13 Nov 2009 17:15:37 +0000</pubDate>
<dc:creator>mwidlake</dc:creator>
<guid>http://mwidlake.wordpress.com/2009/11/13/blevel-and-height-of-indexes/</guid>
<description><![CDATA[I got something wrong on a couple of postings recently, namely the relationship between BLEVEL and t]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>I got something wrong on a couple of postings recently, namely the relationship between BLEVEL and the number of blocks needed to read &#8220;down&#8221; an index, the true depth or HEIGHT of the index {I used to know this but I forgot, but heck no one pinged me on the two posts in question, so I got away with it <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  &#8211; I&#8217;ve updated the postings already.}</p>
<p>BLEVEL is the number of branch levels (including the root node) in a B-Tree index. Height is the actual depth of the index. Height is BLEVEL plus one. So when you see BLEVEL of 3 against an index in DBA_INDEXES/DBA_IND_STATISTICS, that means the index has a root node, a first level of Branch blocks, then a second level of branch blocks and finally the Leaf blocks (that hold the indexed values and rowids to the table entries).</p>
<p>Thus to scan the index for one unique entry, Oracle will need to read the root node to locate the correct branch node in branch level one, read that to find the correct branch node in branch level 2 and that will lead to the correct leaf block. That is four blocks to read. The leaf block contains the index entry and the rowid of the relevant data block, which allows oracle to go directly to that block, for the fifth block read.</p>
<p>{I&#8217;m having trouble finding a nice diagram of this {{ I hate the one in the Oracle manuals}}, not even on Mr Foote&#8217;s or Mr Lewis&#8217;s pages, so if you spot one before I do, let me know and I&#8217;ll update this page with a relevant link}.</p>
<p>Some documentation on the Web mentions HEIGHT being held in the index stats table. This is SYS.INDEX_STATS, not the DBA_IND_STATISTICS table, and SYS.INDEX_STATS is only populated when you run the old &#8220;ANLAYZE INDEX <em>index_name</em> VALIDATE STRUCTURE&#8221; command, so ignore that.</p>
<p>The below demonstrates the increasing BLEVEL and the number of consistent gets to <em>select one record</em> {it&#8217;s more complicated if you select more than one}</p>
<pre class="brush: sql;">NAME                           VALUE
------------------------------ --------------------
compatible                     10.2.0.3.0
cpu_count                      8
db_block_size                  8192
db_file_multiblock_read_count  16
optimizer_mode                 ALL_ROWS
sga_target                     0
sort_area_size                 65536

create table test_bl
 (id    number(8) not null
 ,status number(1) not null
 ,num_1     number(3) not null -- random 20
 ,num_2     number(3) -- random 20
 ,num_3     number(5) -- cycle smoothly
 ,num_4     number(5) -- cycle smoothly
 ,vc_1      varchar2(10)
 ,vc_2      varchar2(10)
 ,vc_pad varchar2(2000))
 tablespace users
 /
Table created.

insert into test_bl(id,status,num_1,num_2,num_3,num_4
                   ,vc_1,vc_2,vc_pad)
select rownum,decode(mod(rownum,100),0,1
               ,0)
,trunc(dbms_random.value(1,20))
,trunc(dbms_random.value(1,30))
,mod(rownum,10)+1
,mod(rownum,100)+1
,dbms_random.string('U',10)
,lpad(chr(mod(rownum,6)+65),5,chr(mod(rownum,6)+65) )
,lpad('A',100,'A')
from dba_objects
where rownum &#60; 500
/
499 rows created.

commit;
Commit complete.

-- now add a pK on the ID
alter table test_bl
add constraint tb_pk primary key (id)
using index
tablespace users
 /
Table altered.

begin
  dbms_stats.gather_table_stats(user,'TEST_BL');
END;
/
PL/SQL procedure successfully completed.

select index_name,blevel,leaf_blocks
from dba_indexes
where owner=user
and index_name like 'TB%'
/

INDEX_NAME                         BLEVEL LEAF_BLOCKS
------------------------------ ---------- -----------
TB_PK                                   0           1</pre>
<p>So I&#8217;ve created the test table, put 499 records in it and added the index, via a primary key constraint. The index created has one leaf block in it and a BLEVEL of 0.</p>
<p>Now let&#8217;s select a record via it {and the reason I put 499 records in the table is so that oracle decides to use the index and not a full table scan, which would be a danger with a very small table}.</p>
<pre class="brush: sql;">set autotrace on
select vc_1 from test_bl where id=54
 /

VC_1
----------
BRFVRHEMWP
1 row selected.

Execution Plan
----------------------------------------------------------
&#124; Id&#124; Operation                   &#124; Name    &#124; Rows  &#124;Bytes&#124; Cost&#124;
----------------------------------------------------------
&#124; 0 &#124; SELECT STATEMENT            &#124;         &#124;    1 &#124;  15 &#124;  1  (0)&#124;
&#124; 1 &#124;  TABLE ACCESS BY INDEX ROWID&#124; TEST_BL &#124;    1 &#124;  15 &#124;  1  (0)&#124;
&#124;*2 &#124;   INDEX UNIQUE SCAN         &#124; TB_PK   &#124;    1 &#124;     &#124;  0  (0)&#124;
----------------------------------------------------------

Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
          2  consistent gets
          0  physical reads
          0  redo size
        339  bytes sent via SQL*Net to client
        338  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

select vc_1 from test_bl where id=54
 /

VC_1
----------
BRFVRHEMWP
1 row selected.

Execution Plan
----------------------------------------------------------
&#124;Id &#124; Operation                   &#124; Name    &#124; Rows &#124;Bytes&#124; Cost
----------------------------------------------------------
&#124; 0 &#124; SELECT STATEMENT            &#124;         &#124;    1 &#124;  15 &#124; 1   (0)&#124;
&#124; 1 &#124;  TABLE ACCESS BY INDEX ROWID&#124; TEST_BL &#124;    1 &#124;  15 &#124; 1   (0)&#124;
&#124;*2 &#124;   INDEX UNIQUE SCAN         &#124; TB_PK   &#124;    1 &#124;     &#124; 0   (0)&#124;
-----------------------------------------------------------

Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          2  consistent gets
          0  physical reads</pre>
<p>I generally run test selects twice, to remove any parsing and recursive SQL overhead {I&#8217;ll remove these from the rest of this post}. So, 2 consistent gets. That would be one on the index and one on the table then.<br />
Note the cost of the index index unique scan &#8211; 0. See end. </p>
<p>Now I&#8217;ll add more data and grow the index.</p>
<pre class="brush: sql;">test102&#62;set autotrace off echo off
insert into test_bl(id,status,num_1,num_2,num_3,num_4
                  ,vc_1,vc_2,vc_pad)
select rownum+500,decode(mod(rownum,100),0,1
              ,0)
,trunc(dbms_random.value(1,20))
,trunc(dbms_random.value(1,30))
,mod(rownum,10)+1
,mod(rownum,100)+1
,dbms_random.string('U',5)
,lpad(chr(mod(rownum,6)+65),5,chr(mod(rownum,6)+65) )
,lpad('A',100,'A')
from dba_objects
where rownum &#60; 5500
/
5499 rows created.

begin
  dbms_stats.gather_table_stats(user,'TEST_BL');
END;
/
PL/SQL procedure successfully completed.

select index_name,blevel,leaf_blocks
from dba_indexes
where owner=user
and index_name like 'TB%'
/

INDEX_NAME                         BLEVEL LEAF_BLOCKS
------------------------------ ---------- -----------
TB_PK                                   1          11</pre>
<p>So now we have a BLEVEL of 1 and 11 leaf blocks. That will be a root node and below it the leaf blocks. Let&#8217;s try a select:</p>
<pre class="brush: sql;">select vc_1 from test_bl where id=454
/
VC_1
----------
IQGSEOCCCH

Execution Plan
----------------------------------------------------------
&#124;Id &#124; Operation                   &#124; Name    &#124; Rows  &#124;Bytes&#124; Cost&#124;
----------------------------------------------------------
&#124; 0 &#124; SELECT STATEMENT            &#124;         &#124;     1 &#124;  11 &#124; 2   (0)&#124;
&#124; 1 &#124;  TABLE ACCESS BY INDEX ROWID&#124; TEST_BL &#124;     1 &#124;  11 &#124; 2   (0)&#124;
&#124;*2 &#124;   INDEX UNIQUE SCAN         &#124; TB_PK   &#124;     1 &#124;     &#124; 1   (0)&#124;
-----------------------------------------------------------

Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          3  consistent gets
          0  physical reads
</pre>
<p>3 consistent gets, one for the root node, one for the relevant leaf block and one for the data block holding the record.</p>
<p>Now I&#8217;ll insert about 400,000 more records to cause the index to become one level deeper. You might be interested to know that 300,000 records was not enough to cause a layer of branch nodes to be created, though as I am indexing an ascending numerical column, each index entry is not exactly huge.<br />
I will then select my record:</p>
<pre class="brush: sql;">99999 rows created.
99999 rows created.
99999 rows created.
99999 rows created.

begin
  dbms_stats.gather_table_stats(ownname=&#62;user,tabname =&#62;'TEST_BL'
                                ,estimate_percent=&#62; 10);
END;
 /
PL/SQL procedure successfully completed.

INDEX_NAME                         BLEVEL LEAF_BLOCKS
------------------------------ ---------- -----------
TB_PK                                   2         761

set autotrace on
select vc_1 from test_bl where id=454
 /

VC_1
----------
IQGSEOCCCH
1 row selected.

Execution Plan
----------------------------------------------------------
&#124;Id &#124; Operation                   &#124; Name    &#124; Rows  &#124;Bytes&#124; Cost&#124;
--------------------------------------------------------
&#124; 0 &#124; SELECT STATEMENT            &#124;         &#124;     1 &#124;  12 &#124; 3   (0)&#124;
&#124; 1 &#124;  TABLE ACCESS BY INDEX ROWID&#124; TEST_BL &#124;     1 &#124;  12 &#124; 3   (0)&#124;
&#124;*2 &#124;   INDEX UNIQUE SCAN         &#124; TB_PK   &#124;     1 &#124;     &#124; 2   (0)&#124;
---------------------------------------------------------

Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          4  consistent gets
          0  physical reads
</pre>
<p>The index BLEVEL has gone up to 2 {index height is 3} and now 4 consistent gets are needed to fetch the record.</p>
<p>You may have noticed that the estimated cost of the INDEX_UNIQUE_SCAN is the same as the BLEVEL, which is not really correct. After all, in the first example the cost was 0 and there has to be a read of the index leaf block! The costing makes more sense when it is part of the calculation for scanning an index and then visiting the table for all found records:-</p>
<p>&#8220;basic index range scan cost = index blevel + ceil(index selectivity x leaf blocks) + ceil(table selectivity x clustering factor)&#8221;</p>
<p>In words this formula means &#8220;go down the index to the lead nodes (this is the BLEVEL), scan the number of leaf nodes expected for this index value, then visit the number of table blocks this set of index entries would map to&#8221;.</p>
<p>For more information on the formula, I&#8217;d plug part of that formula into google (or bing or whatever takes your fancy, search-engine-wise). The original is <a href="http://richardfoote.wordpress.com/category/oracle-cost-based-optimizer/">this page by Richard Foote</a> but there are some good notes by others as well.</p>
<p>There are a lot of references on the web about the cost of accesing an index being the BLEVEL, but remember, if it is a unique access it is the BLEVEL plus one, and oracle seems (in my little tests anyway) to be underestimating the cost by 1. I think this reference to the BLEVEL and the costs might be leading to people (like me, hehe, mistaking the BLEVEL as the actual height of the index.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[What happens when you run a Data Refresh within #PowerPivot for SharePoint?]]></title>
<link>http://dennyglee.com/2009/11/08/what-happens-when-you-run-a-data-refresh-within-powerpivot-for-sharepoint/</link>
<pubDate>Sun, 08 Nov 2009 23:48:12 +0000</pubDate>
<dc:creator>dennyglee</dc:creator>
<guid>http://dennyglee.com/2009/11/08/what-happens-when-you-run-a-data-refresh-within-powerpivot-for-sharepoint/</guid>
<description><![CDATA[I was just recently asked the question by a fellow Analysis Services expert (Greg Galloway): When yo]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>I was just recently asked the question by a fellow Analysis Services expert (<a href="http://www.artisconsulting.com/blogs/greggalloway/default.aspx">Greg Galloway</a>):</p>
<blockquote><p>When you have SharePoint automate a data refresh for a PowerPivot workbook, is the new data saved back into the xlsx? So if I download the xlsx onto my laptop the next day, will I see fresh data? Also, if the xlsx is updated by SharePoint during data refresh, is that step subject to the 2GB file limit?</p></blockquote>
<p>and I thought it made sense if that we share this answer as well.</p>
<p>So the answer is “Yes”.</p>
<p>…</p>
<p>Details you ask? Okay, here are the basic constructs:</p>
<p><a href="http://powerpivottwins.com/2009/11/08/what-happens-when-you-run-a-data-refresh-within-powerpivot-for-sharepoint/">Read more&#8230;</a></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Metalink | Read Only ... Migrando]]></title>
<link>http://aguimaraes.wordpress.com/2009/11/08/metalink-read-only-migrando/</link>
<pubDate>Sun, 08 Nov 2009 22:19:20 +0000</pubDate>
<dc:creator>agleite</dc:creator>
<guid>http://aguimaraes.wordpress.com/2009/11/08/metalink-read-only-migrando/</guid>
<description><![CDATA[Disponibilidade 24&#215;7 &#8230;sei ORA-00372: file 28 cannot be modified at this time ORA-01110: d]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Disponibilidade 24&#215;7 &#8230;sei <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>ORA-00372: file 28 cannot be modified at this time ORA-01110: data file 28: &#8216;/u01/app/oracle/admin/mlrepap/db/metalink_02.dbf&#8217; </p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[What happens when you run a Data Refresh within #PowerPivot for SharePoint?]]></title>
<link>http://powerpivottwins.com/2009/11/08/what-happens-when-you-run-a-data-refresh-within-powerpivot-for-sharepoint/</link>
<pubDate>Sun, 08 Nov 2009 17:08:59 +0000</pubDate>
<dc:creator>dennyglee</dc:creator>
<guid>http://powerpivottwins.com/2009/11/08/what-happens-when-you-run-a-data-refresh-within-powerpivot-for-sharepoint/</guid>
<description><![CDATA[I was just recently asked the question by a fellow Analysis Services expert (Greg Galloway): When yo]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>I was just recently asked the question by a fellow Analysis Services expert (<a href="http://www.artisconsulting.com/blogs/greggalloway/default.aspx">Greg Galloway</a>):</p>
<blockquote><p>When you have SharePoint automate a data refresh for a PowerPivot workbook, is the new data saved back into the xlsx? So if I download the xlsx onto my laptop the next day, will I see fresh data? Also, if the xlsx is updated by SharePoint during data refresh, is that step subject to the 2GB file limit?</p></blockquote>
<p>and I thought it made sense if that we share this answer as well.</p>
<p>So the answer is “Yes”.</p>
<p>…</p>
<p>Details you ask? Okay, here are the basic constructs:</p>
<ul>
<li>
<div>When Data Refresh is started, PowerPivot service will reference an existing IMBI database (if it exists) within the Analysis Services Engine Service running within the SharePoint farm</div>
</li>
<li>
<div>Or it will pull the database out of the Excel workbook (upon getting the workbook from the SharePoint content database) and attach it to one of the Analysis Services Engine SharePoint Service.  Since it is a service within SharePoint, it makes use of the SharePoint load balancing service (within the farm) to choose which Analysis Services Engine Service to use.  By default, it uses the health-based monitoring to determine on which server to put the database.</div>
</li>
<li>
<div>The Data Refresh kicks off and the data is imported into the database running in the Analysis Services Engine SharePoint Service.</div>
</li>
<li>
<div>Now that the data is refreshed, the database will be pushed back into the Excel workbook and then saved back to the SharePoint content database.</div>
</li>
<li>
<div>Because it is saved in the SharePoint content database, indeed it will be constrained to the 2GB limitation.</div>
</li>
<li>
<div>From this point, when you download the file after the data refresh, it will now contain the latest and greatest data.</div>
</li>
</ul>
<p>Later on, I will do blog post based on the high level architecture that may help provide a little better context in all of this as well.</p>
<p>Enjoy!</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Understanding why an Excel PowerPivot workbook is so large]]></title>
<link>http://powerpivottwins.com/2009/11/07/understanding-why-an-excel-powerpivot-workbook-is-so-large/</link>
<pubDate>Sat, 07 Nov 2009 08:13:25 +0000</pubDate>
<dc:creator>dennyglee</dc:creator>
<guid>http://powerpivottwins.com/2009/11/07/understanding-why-an-excel-powerpivot-workbook-is-so-large/</guid>
<description><![CDATA[During my and Dave Wickert’s SQLPASS session (SQLCAT: A Preview to PowerPivot Best Practices), we ha]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p align="left">During my and Dave Wickert’s SQLPASS session (SQLCAT: A Preview to PowerPivot Best Practices), we had shown to the audience how to view and better understand the PowerPivot database file structure within the Excel workbook.&#160; First of all, I&#8217;d like to give credit where credit is due – and the thanks really should go to <strong>Ashvini Sharma</strong> – Power Pivot, Analysis Services, and Integration Services Dev MasterMind.&#160; So while the presentation piece is ours – the actual knowledge and know how is his <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> .</p>
<p align="left">Saying this, what do we mean by all of this? </p>
<p align="left">For starters, recall that an Excel utilizing the PowerPivot add-in actually contains the database within the Excel workbook.&#160; For more information on this, please refer to <a href="http://powerpivottwins.com/2009/11/07/for-excel-powerpivot-the-database-is-in-the-workbook/">For Excel PowerPivot, the database is IN the workbook</a>.</p>
<p align="left">But now that you know that the database is IN the workbook, how can you find out why the workbook is so large as my esteemed PowerPivot twitter @VidasM recently inquired?</p>
<p align="left">Well, if you recall from the presentation or blog post, when Excel utilizes PowerPivot, it makes use of the VertiPaq database.&#160; While the database is primarily in-memory, it will have an on-disk structure for it cache against before finally saving itself into the workbook itself (when saved and no longer in use).&#160; To find this temporary cache folder, </p>
<ul>
<li>
<div align="left">Open up an Excel PowerPivot workbook</div>
</li>
<li>
<div align="left">Go to your %TEMP% folder (e.g. c:\Users\MyName\AppData\Local\Temp) and find the IMBI_&#60;GUID&#62; folder.&#160; If there are multiple IMBI_&#60;GUID&#62; folders, find the most recent one</div>
</li>
<li>
<div align="left">When you open up this folder, for those of you who work regularly with Analysis Services, this file structure will be very familiar as it is very similar to your native Analysis Services data folder structure.</div>
</li>
</ul>
<p align="left"><a href="http://powerpivottwins.files.wordpress.com/2009/11/image3.png"><img style="border-bottom:0;border-left:0;display:inline;border-top:0;border-right:0;" title="image" border="0" alt="image" src="http://powerpivottwins.files.wordpress.com/2009/11/image_thumb3.png?w=531&#038;h=377" width="531" height="377" /></a>&#160;</p>
<ul>
<li>
<div align="left">Within the [Search Box] (upper right hand corner of your Windows Explorer for those using Windows 7) and type <strong>*.* </strong>and sort by size.</div>
</li>
</ul>
<p align="left"><a href="http://powerpivottwins.files.wordpress.com/2009/11/image4.png"><img style="border-bottom:0;border-left:0;display:inline;border-top:0;border-right:0;" title="image" border="0" alt="image" src="http://powerpivottwins.files.wordpress.com/2009/11/image_thumb4.png?w=641&#038;h=338" width="641" height="338" /></a>&#160;</p>
<ul>
<li>
<div align="left">By doing so, you can now identify which IDF and dictionary files exist and which files are larger which correspond to the tables and columns you have imported.</div>
</li>
</ul>
<p align="left">While we have yet to develop best practices, the basic principal here is by doing this, you will be able to find the tables and columns that are taking up alot of space within your Excel PowerPivot workbook and can potentially remove any columns that are not required.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[For Excel PowerPivot, the database is IN the workbook]]></title>
<link>http://powerpivottwins.com/2009/11/07/for-excel-powerpivot-the-database-is-in-the-workbook/</link>
<pubDate>Sat, 07 Nov 2009 07:51:59 +0000</pubDate>
<dc:creator>dennyglee</dc:creator>
<guid>http://powerpivottwins.com/2009/11/07/for-excel-powerpivot-the-database-is-in-the-workbook/</guid>
<description><![CDATA[Concerning Excel PowerPivot, the question is often asked how is it possible for Excel to now handle ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p align="left">Concerning Excel PowerPivot, the question is often asked how is it possible for Excel to now handle tens or hundreds of millions of rows – the way native Excel handles tens or hundreds of thousands of rows.&#160; </p>
<p align="left">How you ask?&#160; </p>
<p align="left">Well, the reason why is because Excel (with the PowerPivot add-in) is using the new In-Memory BI (IMBI) database.&#160; It utilizes a column-based store which has been seen academically and empirically to have some interesting characteristics within BI scenarios…namely, it can calculate many (but not all) BI aggregate very quickly.&#160; Because it is in-memory, it does not utilize disk I/O and performs all of its scans in-memory – i.e. much faster because you do not have disk contention.&#160; As well, it has a great compression algorithm in order to significantly reduce the size of the overall data stored.&#160; By the way, this new database architecture is called VertiPaq for all those interested in the trivia!</p>
<p align="left">So while Vertipaq is really cool, what does this have to do with Excel PowerPivot?&#160; Well, the reason is because the PowerPivot database is actually in the workbook itself.&#160; To prove it, here’s what you can do:</p>
<ul>
<li>
<div align="left">Take your Excel PowerPivot workbook, which you’ll notice is typically much larger than your typical native Excel workbooks</div>
</li>
<li>
<div align="left">Copy the Excel file and rename it using a .zip extension instead of a .xlsx.&#160; Note, the reason why is because .xlsx is actually XML</div>
</li>
</ul>
<p align="left"><a href="http://powerpivottwins.files.wordpress.com/2009/11/image.png"><img style="border-bottom:0;border-left:0;display:inline;border-top:0;border-right:0;" title="image" border="0" alt="image" src="http://powerpivottwins.files.wordpress.com/2009/11/image_thumb.png?w=660&#038;h=133" width="660" height="133" /></a> </p>
<ul>
<li>
<div align="left">When you open up the .zip file, you’ll notice a lot of various folders within it (as noted, it’s all XML).</div>
</li>
</ul>
<p align="left"><a href="http://powerpivottwins.files.wordpress.com/2009/11/image1.png"><img style="border-bottom:0;border-left:0;display:inline;border-top:0;border-right:0;" title="image" border="0" alt="image" src="http://powerpivottwins.files.wordpress.com/2009/11/image_thumb1.png?w=447&#038;h=124" width="447" height="124" /></a>&#160;</p>
<ul>
<li>
<div align="left">Open up the <strong>xl </strong>folder, and then you’ll notice the <strong>customData</strong> folder.&#160; When you navigate to it, you’ll notice the <strong>item1.data</strong> file which contains the bulk of the size of the Excel file</div>
</li>
</ul>
<p align="left"><a href="http://powerpivottwins.files.wordpress.com/2009/11/image2.png"><img style="border-bottom:0;border-left:0;display:inline;border-top:0;border-right:0;" title="image" border="0" alt="image" src="http://powerpivottwins.files.wordpress.com/2009/11/image_thumb2.png?w=451&#038;h=80" width="451" height="80" /></a> </p>
<p align="left">This item1.data file is your PowerPivot database stored right IN the Excel file.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[फ़िर से exams]]></title>
<link>http://chheherazaad.wordpress.com/2009/11/02/%e0%a5%9e%e0%a4%bf%e0%a4%b0-%e0%a4%b8%e0%a5%87-exams/</link>
<pubDate>Mon, 02 Nov 2009 17:42:27 +0000</pubDate>
<dc:creator>Shehrazad</dc:creator>
<guid>http://chheherazaad.wordpress.com/2009/11/02/%e0%a5%9e%e0%a4%bf%e0%a4%b0-%e0%a4%b8%e0%a5%87-exams/</guid>
<description><![CDATA[क्या तकलीफ है मुझे समझ नहीं आता. जब से engineering मोल ली है यब से जान की आफत बने बैठे हैं ये exams.]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>क्या तकलीफ है मुझे समझ नहीं आता. जब से engineering मोल ली है यब से जान की आफत बने बैठे हैं ये  exams. अब कल से फिर चालू. दुखी ही कर रखा है.<br />
अब तो inert ही हो गए हैं. हर महीने दे दे के exams अब फर्क पड़ना ही बंद हो गया है. </p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[ Find waiter with Oradebug 11gR2  ]]></title>
<link>http://oraclue.com/2009/10/29/find-waiter-with-oradebug-11gr2/</link>
<pubDate>Thu, 29 Oct 2009 13:41:46 +0000</pubDate>
<dc:creator>oraclue</dc:creator>
<guid>http://oraclue.com/2009/10/29/find-waiter-with-oradebug-11gr2/</guid>
<description><![CDATA[There is small addition to oradebug unit_test command in 11g R2 . oradebug unit_test per_session_fin]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>There is small addition to oradebug unit_test command in 11g R2 .</p>
<p><strong>oradebug unit_test per_session_find_one_waiter</strong></p>
<p>This command has four mandatory arguments and one optional.</p>
<p>First parameter is<strong> find_waiters_for</strong> which can have two different values : current_sess or all_local_sess .Self descriptive.<br />
Second parameter is <strong>wait_event</strong>.This is name of the wait event which search is done.Third and fourth parameters are related to time and rusults.</p>
<p>For my simple test I will test this command on event enq TX -row lock contention for my own session.</p>
<p>Session 1:</p>
<p>create table test(a int primary key);</p>
<p>insert into test select rownum from dba_tables where rownum &#60;9;<br />
commit;<br />
update test set a=9 where a=1;<br />
update test set a=10 where a=2;</p>
<p>Session 2:</p>
<p>update test set a=11 where a=3;<br />
update test set a=12 where a=4;</p>
<p>SQL&#62; /</p>
<p>PID SPID                            SID USERNAME                          SERIAL# SQL_HASH_VALUE<br />
&#8212;&#8212;&#8212;- &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; &#8212;&#8212;&#8212;- &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; &#8212;&#8212;&#8212;- &#8212;&#8212;&#8212;&#8212;&#8211;<br />
22 1030                            190 SYS                                  1115     3889092034</p>
<p>Session 1 again:</p>
<p>SQL&#62; /</p>
<p>PID SPID                    SID USERNAME                          SERIAL# SQL_HASH_VALUE<br />
&#8212;&#8212;&#8212;- &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; &#8212;&#8212;&#8212;- &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; &#8212;&#8212;&#8212;- &#8212;&#8212;&#8212;&#8212;&#8211;<br />
21 31360                   156 SYS                                 59123     3889092034</p>
<p>update test set a=25 where a=8;<br />
update test set a=13 where a=3;</p>
<p>Now I got  event to test oradebug command:</p>
<p><strong>oradebug unit_test per_session_find_one_waiter find_waiters_for=current_sess wait_event=&#8221;enq: TX &#8211; row lock contention&#8221; waiter_min_secs_blkd=300 min_results=1</strong></p>
<p>SQL&#62; oradebug unit_test per_session_find_one_waiter find_waiters_for=current_sess wait_event=&#8221;enq: TX &#8211; row lock contention&#8221; waiter_min_secs_blkd=1 min_results=1</p>
<p>Here is output:</p>
<p><strong>WAITERS_FOUND_BEGIN<br />
(inst=1, sid=190, osid=1030) is blocking (inst=1, sid=156) for at least 74 secs<br />
WAITERS_FOUND_END</strong></p>
<p>if I run same command again</p>
<p>SQL&#62; oradebug unit_test per_session_find_one_waiter find_waiters_for=current_sess wait_event=&#8221;enq: TX &#8211; row lock contention&#8221; waiter_min_secs_blkd=1 min_results=1</p>
<p>WAITERS_FOUND_BEGIN<br />
(inst=1, sid=190, osid=1030) is blocking (inst=1, sid=156) for at least 221 secs<br />
WAITERS_FOUND_END</p>
<p>wait time will increase.</p>
<p>Let&#8217;s increase waiter_min_secs_blkd=300 and run command:</p>
<p>SQL&#62; oradebug unit_test per_session_find_one_waiter find_waiters_for=current_sess wait_event=&#8221;enq: TX &#8211; row lock contention&#8221; waiter_min_secs_blkd=300 min_results=1<br />
WAITERS_FOUND_BEGIN<br />
(inst=1, sid=190, osid=1030) is blocking (inst=1, sid=156) for at least 301 secs<br />
WAITERS_FOUND_END</p>
<p>and I got output after aprox 301 secs..</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Accessing Roles in stored PL/SQL]]></title>
<link>http://mwidlake.wordpress.com/2009/10/22/accessing-roles-in-stored-plsql/</link>
<pubDate>Thu, 22 Oct 2009 20:41:20 +0000</pubDate>
<dc:creator>mwidlake</dc:creator>
<guid>http://mwidlake.wordpress.com/2009/10/22/accessing-roles-in-stored-plsql/</guid>
<description><![CDATA[Whilst looking for the minimum privileges I needed to execute DBMS_STATS.FLUSH_DATABASE_MONITORING_I]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Whilst looking for <a href="http://mwidlake.wordpress.com/2009/10/19/">the minimum privileges I needed to execute DBMS_STATS.FLUSH_DATABASE_MONITORING_INFO</a> {it is ANALYZE ANY, by the way} I discovered something about PL/SQL and roles that I did not know. Now, any right I had to claim expertise in PL/SQL expired at least 8 years ago but I asked some friends who ARE still professional PL/SQL experts and they did not know this either.</p>
<p>Privileges granted via Roles to a user are not available to stored PL/SQL created by that user, correct? This is widely known and understood. You have to grant priveleges directly to the user for them to be seen in the PL/SQL packages, functions etc.</p>
<p>Having found that I needed the ANALYZE ANY privilege as I mentioned above, I asked the DBA team to grant my user that privilege on Production and Staging. They did so &#8211; via a role. &#8220;it won&#8217;t work&#8221; I said &#8220;I run the code via a package, it won&#8217;t see the privilege&#8221; and proved it by running DBMS_STATS.FLUSH_DATABASE_MONITORING_INFO via a quickly constructed demo. Except I only proved my ignorance, it worked. WHY?</p>
<p>If a package is created such that it is executed <em>with invokers rights</em> then <strong>roles are seen</strong>. </p>
<p>This is my test script:</p>
<pre class="brush: sql;">create or replace package test1 is
procedure run_flush;
end test1;
/
--
create or replace package test1 authid current_user is
procedure run_flush is
cursor get_ses_roles is
select role
from session_roles;
begin
  dbms_output.put_line('starting');
  for ses_roles_rec in get_ses_roles loop
    dbms_output.put_line(ses_roles_rec.role);
  end loop;
  dbms_output.put_line('flushing');
  dbms_stats.flush_database_monitoring_info;
  dbms_output.put_line('ending');
end;
begin
  null;
end;
/</pre>
<p>I create this package as user MDW.</p>
<p>Now as a privileged user I create a role and grant analyze_any to the role.</p>
<pre class="brush: sql;">MGR&#62;create role mdw_role
Role created.
MGR&#62;grant analyze any to mdw_role;
Grant succeeded.</pre>
<p>I&#8217;ll just prove that user MDW cannot yet execute the monitoring procedure</p>
<pre class="brush: sql;">MDW&#62; exec dbms_stats.flush_database_monitoring_info
BEGIN dbms_stats.flush_database_monitoring_info; END;
*
ERROR at line 1:
ORA-20000: Insufficient privileges
ORA-06512: at &#34;SYS.DBMS_STATS&#34;, line 2148
ORA-06512: at &#34;SYS.DBMS_STATS&#34;, line 14135
ORA-06512: at line 1</pre>
<p>Now I grant the role</p>
<pre class="brush: sql;">MGR&#62;grant mdw_role to mdw
Grant succeeded.</pre>
<p>MDW has to log out and back in again to see the role correctly. Having done this I check for the role and then try to execute the test procedure:</p>
<pre class="brush: sql;">MDW&#62; select * from session_roles

ROLE
------------------------------
CONNECT
MDW_ROLE
2 rows selected.

MDW&#62; exec test1.run_flush
starting
CONNECT
MDW_ROLE
flushing
ending

PL/SQL procedure successfully completed.</pre>
<p>You can see that the package sees the roles and it executes the procedure successfully. So, <strong>stored PL/SQL can utilise privileges via roles if the packages is created with authid current_user</strong>, ie executors rights.</p>
<p>I better admit, as someone else might raise it, that this is not the best demonstration of this feature. I recreated the package with the first line set to:</p>
<p>create or replace package test1 is</p>
<p>ie the default of owners privileges. I now re-execute the call to the package:-</p>
<pre class="brush: sql;">MDW&#62; exec test1.run_flush
starting
flushing
ending

PL/SQL procedure successfully completed.
</pre>
<p>Note that the roles are no longer seen. However, the DBMS_STATS.FLUSH_DATABASE_MONITORING_INFO still executed correctly.<br />
Why?<br />
Well, because if you look at the package specification of DBMS_STATS you see:-</p>
<p>create or replace package sys.dbms_stats authid current_user is</p>
<p>It makes sense. It is dangerous for system-owned packages to be executing as the owner, ie SYS, as execute access to the package would allow access to SYS privileges.</p>
<p>Which, of course, is why my little proof script executed the flush correctly and I looked a bit silly in front of the DBA team. Oh well.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[The Sequence of an Index Uniquifier ]]></title>
<link>http://sqlfascination.com/2009/10/20/the-sequence-of-an-index-uniquifier/</link>
<pubDate>Tue, 20 Oct 2009 20:46:29 +0000</pubDate>
<dc:creator>andrewhogg</dc:creator>
<guid>http://sqlfascination.com/2009/10/20/the-sequence-of-an-index-uniquifier/</guid>
<description><![CDATA[During a training session today, I was asked about the structure of the Uniquifier, and whether it w]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>During a training session today, I was asked about the structure of the Uniquifier, and whether it was a straight identity column. Off the top of my head I couldn&#8217;t remember the exact structure, I considered it a 4 byte int, but was not sure whether it acted as a pure identity value or acted in a more complex manner when incrementing, so decided to investigate it tonight.</p>
<p>To start from the beginning, an index uniquifier is the term given to the field that is automatically generated by SQL Server when you create a clustered index, but the index key is not specified as unique. Since each record in the table has to be uniquely identifiable, SQL will automatically assigned a 4 byte field to the row to make it unique, commonly called the &#8216;Uniquifier&#8217;. At this point I am sure English scholars will be frowning, pondering on the nature of the word and whether it qualifies as English; however that the term used so we will run with it.</p>
<p>It is actually quite easy to see this field in action, let&#8217;s create a simple table:</p>
<pre>CREATE TABLE dbo.unique_test  (  
firstname char(20) NOT NULL,  
surname char(20) NOT NULL  
)  ON [PRIMARY] GO
CREATE CLUSTERED INDEX [ix_test] ON [dbo].[unique_test]
 (
[firstname] ASC
)
ON [PRIMARY]</pre>
<p>The clustered index is not unique, by design, so let&#8217;s start adding duplicate rows to see the effect:</p>
<pre>insert into unique_test values ('John', 'Smith')
go 10</pre>
<p>The table now contains 10 rows, each with the same details. This does not cause any undue concern, because each row is actually still unique &#8211; the way to show this is using the DBCC INC and DBCC Page commands, I&#8217;ve cut the output down since it is so wide.</p>
<pre>dbcc ind ('testdb','unique_test',1)
PageFID PagePID     IAMFID IAMPID      PageType
------- ----------- ------ ----------- --------
1       41          NULL   NULL        10      
1       174         1      41          1       </pre>
<p>The output shows a data page numbered 174 for my example and the IAM page with an ID of 41. We can crack open the page and view the contents very easily using DBCC Page.</p>
<pre>dbcc dbcc traceon(3604)
dbcc page (idtest,1,174,3)</pre>
<p>The output is quite large, but in essence, the first record is stored with the following details: </p>
<pre>UNIQUIFIER = [NULL]                 
Slot 0 Column 1 Offset 0x4 Length 20
firstname = John                    
Slot 0 Column 2 Offset 0x18 Length 20</pre>
<p> The second record:</p>
<pre>Slot 1 Column 0 Offset 0x33 Length 4
UNIQUIFIER = 1                      
Slot 1 Column 1 Offset 0x4 Length 20
firstname = John                    
Slot 1 Column 2 Offset 0x18 Length 20
surname = Smith  </pre>
<p> The third record:</p>
<pre>Slot 2 Column 0 Offset 0x33 Length 4
UNIQUIFIER = 2                      
Slot 2 Column 1 Offset 0x4 Length 20
firstname = John                    
Slot 2 Column 2 Offset 0x18 Length 20
surname = Smith                     </pre>
<p>And so forth. The first record&#8217;s uniquifier is visible and clearly named within the data page, but set to null. The second copy of the same value receives the uniquifier of one, the third copy receives a 2 etc.  This count is maintained separately for each duplication, so the insert of a new name multiple times will also receive its own counter, beginning at null and working upwards, 1,2,3 etc. So just because the uniquifier is 4 bytes, this does not limit the total number of rows in the table to ~2.1 billion, but does logically limit the total number of duplicates to 2.1 billion. I must confess to not having tested that limit, generating 2.1 billion rows of duplicate data is not trivial and a scrapbook calculation predicts 435 hours of processing on a virtual pc. I suspect the error message it raises when it hits the limit would be interesting.</p>
<p>If we remove all the rows from the table and then add 10 more does the uniquifier reset? Easy to test but the short answer was no, the uniquifier continued to rise, 10 thru 19.</p>
<p>I was a bit suspicious of this since any requirement for the uniquifier to rise / remember what existed before requires it to be stored somewhere &#8211; it has to survive a crash after all, but there is no apparent place the current count is stored. If there was, you wouldn&#8217;t be storing just 1 value, you would be forced to store a value for each record key that had duplicates. This could run into thousands of separate counters being maintained per clustered key so it just doesn&#8217;t make sense that it is stored, it would be a very noticable overhead.</p>
<p>When checking the DBCC Ind for the empty table it insisted it still had a data page, but the only contents of the data page was a single ghost record &#8211; a row that has been marked as deleted. The ghost record was the for the &#8216;John Smith&#8217; with the highest uniquifier before, was this coincidence? The other ghost records had not hung around, so why did this one persist?</p>
<p>I dropped and recreated the table again, inserted 10 rows and then deleted them. Checking DBCC Ind the table still showed a HoBT IAM allocation page for the table and a data page, the data page contained a single ghost record, the one with a Uniquifier of 9 &#8211; the highest given out when 10 duplicates were added. Even waiting some considerable time the ghost record was not cleaned up, so it appears that it will not delete it.</p>
<p>If I added another duplicate row, it picked up the next number in the sequence (10) and shortly after the ghost record was removed from the page. Very convenient and not a coincidence at all &#8211; the memory of the last uniquifier given out  persists as a ghost record, even if all the duplicates for the table have been removed.  What seems strange is this ghost record hanging about, persisting an entire record, to keep the duplicate count for that key, when no instances of it remain on the table.</p>
<p>It can not possibly do this for every key since the space overhead would become very noticable again, so how does it choose what to persist, the last entry? unfortunately it doesn&#8217;t appear that simple at all, after a number of tests it appeared to only be interested in keeping the ghost entry for the record that had the highest key value, so alphabetically, the one closed to &#8216;Z&#8217; for my example.</p>
<p>Conclusion? On the evidence, whilst the other ghost records still persist for a short time, even deleting and then adding more duplicates can see the number continue from where it left of, but given a short time for the ghost records to be removed the uniquifier will restart the sequence back at Null,1,2 etc. Except in the case of the highest entry from the index perspective, that ghost record decides to stick around until there is another entry using the same key, continuing the sequence, at which point the ghost record then finally disappears.</p>
<p>I can not think of any sensible reason why it would do this, can you?</p>
<p>Overall, the uniquifier is a cost overhead of not having a unique index, and at a cost of 4 bytes, an int identity column makes a lot of sense - for all purposes it acts the same and serves the same purpose but in a far more visible manner &#8211; so it really does not make much sense to rely on the uniquifier provided for you, take control and create your own.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[What is the SQL Server 2008 DateTimeOffset Internal Structure?]]></title>
<link>http://sqlfascination.com/2009/10/13/what-is-the-sql-server-2008-datetimeoffset-internal-structure/</link>
<pubDate>Tue, 13 Oct 2009 19:50:12 +0000</pubDate>
<dc:creator>andrewhogg</dc:creator>
<guid>http://sqlfascination.com/2009/10/13/what-is-the-sql-server-2008-datetimeoffset-internal-structure/</guid>
<description><![CDATA[After decoding the DateTime2 internal structure I thought I would take a quick look at the DateTimeO]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>After decoding the <a title="DateTime2 Internal Structure" href="http://sqlfascination.com/2009/10/11/what-is-the-sql-server-2008-datetime2-internal-structure/">DateTime2 internal structure</a> I thought I would take a quick look at the DateTimeOffset structure, since it should not present too many difficulties and post it up quickly, but was surprised at the initial result of a test. It follows the same basic premise that the time portion is followed by the date portion and the time / date is based on a day count from the epoch time of 0001/01/01 and the time the number of intervals since midnight, where the interval is defined by the accuracy.</p>
<p>I was expecting the datetime offset value itself to occupy the additional 2 bytes quoted, and not affect the other values. Bad assumption, as soon as I cracked open a few examples I could immediately see that setting the offset also alters the underlying time / date component values as well.</p>
<p>Using the same comparison methods as before the underlying time value is clearly being adjusted:</p>
<pre>'0001/01/01 00:00:00 -0:00' =&#62; 0x0700000000000000000000
'0001/01/01 00:00:00 -12:00' =&#62; 0x0700E034956400000030FD</pre>
<p>So, even though an offset is being stored, the underlying time is also being altered to match, and the internal storage is using UTC as the reference point. This makes sense as the most valid reference that you could use.</p>
<pre>'0001-01-01 12:00:00.0000000 +00:00' =&#62; 0x0700E03495640000000000
'0001-01-01 00:00:00.0000000 -12:00' =&#62; 0x0700E034956400000030FD</pre>
<p>The same time / date is generated for the two values, but the last two bytes hold the offset and have stored the offset used when the date was initially stored. The underlying storage of the time though is clearly identical in both,  so UTC is the common ground they each get stored again.</p>
<p>The final 2 bytes for the offset are pretty easy to decode, since the pattern is the same as before with a slight twist. The offset time records the number of minutes for the offset in hex, with the first byte of the two being the least significant as before with the time, so you end up reading the two bytes left-to-right and then decode that byte right-to-left.</p>
<p>The twist is that for positive offsets, the value increments 1,2,3, in hex as appropriate, but for negative values, it starts decrementing by considering -1 equal to &#8216;FFFF&#8217;, I&#8217;ve split the hex output into the individual components by adding some spaces to make it easier to read. (Accuracy Code, Time Value, Date Value, Offset Used)</p>
<pre>'2001-01-01 12:00:00.0000000 +00:01' =&#62; 0x07   009A717164   75250B  0100
'2001-01-01 12:00:00.0000000 +00:00' =&#62; 0x07   00E0349564   75250B  0000
'2001-01-01 12:00:00.0000000 -00:01' =&#62; 0x07   0026F8B864   75250B  FFFF</pre>
<p>Since the offsets supported at only +14 hours to -14 hours, there is no risk of the two ranges overlapping. When I think about this a bit more, it is acting as a signed number, -1 being 11111111111 etc. So the 2 bytes at the end is a signed int of the number of minutes offset.</p>
<p>There are a number of time zones in the world that do not occur at exact hourly intervals from UTC, some are on the half hour mark such as Caracas (-4:30) or Delhi (+5:30) to name a few, whilst Kathmandu (+5:45) is even more specific.  In theory the format allows offsets specified to even greater levels of distinction, although I am not sure as to why you would wish to use it. Do you really want an offset of +3:17 minutes? That is potentially scary to consider that as a valid input to the value.</p>
<p>That has made me wonder as to why the accuracy was set so high, when in reality 15 minute intervals would of been sufficient, with a -14 to +14 range, that is 113 different values inclusively, which could be accomodated within a single byte.</p>
<p>So why spend 2 bytes on the format, when 1 was enough? Was it to just be compatible to the ISO format in some way that required it? Not sure.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Multithreaded Applications]]></title>
<link>http://enggtech.wordpress.com/2009/10/12/multithreaded-applications/</link>
<pubDate>Mon, 12 Oct 2009 07:54:02 +0000</pubDate>
<dc:creator>Visitor Blogs</dc:creator>
<guid>http://enggtech.wordpress.com/2009/10/12/multithreaded-applications/</guid>
<description><![CDATA[Managed Threading Threading Objects and Features A process is a collection of virtual memory space, ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><div class="MTPS_CollapsibleRegion">
<div class="CollapseRegionLink">
<div><a id="ctl00_MTCS_main_ctl37_ctl00_ctl02" href="http://msdn.microsoft.com/en-us/library/3e8s7xdd.aspx">Managed Threading</a></div>
<div><a id="ctl00_MTCS_main_ctl37_ctl00_ctl03" href="http://msdn.microsoft.com/en-us/library/9xyf641a.aspx">Threading Objects and Features</a></div>
<p>A <em>process</em> is a collection of virtual memory space, code, data, and system resources. A <em>thread</em> is code that is to be serially executed within a process. A processor executes threads, not processes, so each application has at least one process, and a process always has at least one thread of execution, known as the primary thread. A process can have multiple threads in addition to the primary thread.</p>
<p>Processes communicate with one another through messages, using Microsoft&#8217;s Remote Procedure Call (RPC) technology to pass information to one another. There is no difference to the caller between a call coming from a process on a remote machine and a call coming from another process on the same machine.</p>
<p>When a thread begins to execute, it continues until it is killed or until it is interrupted by a thread with higher priority (by a user action or the kernel&#8217;s thread scheduler). Each thread can run separate sections of code, or multiple threads can execute the same section of code. Threads executing the same block of code maintain separate stacks. Each thread in a process shares that process&#8217;s global variables and resources.</p>
</div>
<div class="CollapseRegionLink">Threads are the basic unit to which an operating system allocates processor time, and more than one thread can be executing code inside that process. Each thread maintains</div>
<div class="CollapseRegionLink">
<ul>
<li>exception handlers,</li>
<li>a scheduling priority, and</li>
<li>a set of structures the system uses to save the thread context until it is scheduled.</li>
</ul>
</div>
<div class="CollapseRegionLink"><strong>The thread context </strong>includes all the information the thread needs to seamlessly resume execution, including</div>
<div class="CollapseRegionLink">
<ul>
<li>the thread&#8217;s set of CPU registers and</li>
<li>stack, in the address space of the thread&#8217;s host process.</li>
</ul>
</div>
<div class="CollapseRegionLink">
<p>The .NET Framework further subdivides an operating system process into lightweight managed subprocesses, called <strong>application domains</strong>, represented by <a id="ctl00_MTCS_main_ctl01" href="http://msdn.microsoft.com/en-us/library/system.appdomain.aspx">System..::.AppDomain</a>. One or more managed threads (represented by <a id="ctl00_MTCS_main_ctl03" href="http://msdn.microsoft.com/en-us/library/system.threading.thread.aspx">System.Threading..::.Thread</a>) can run in one or any number of application domains within the same managed process. Although each application domain is started with a single thread, code in that application domain can create additional application domains and additional threads. The result is that a managed thread can move freely between application domains inside the <strong>same managed process; </strong>you might have only one thread moving among several application domains.</p>
</div>
<div class="CollapseRegionLink">If your application uses only one thread of execution, you can combine <a id="ctl00_MTCS_main_ctl23_ctl00_ctl00" href="http://msdn.microsoft.com/en-us/library/2e08f6yc.aspx">asynchronous programming</a> with <a id="ctl00_MTCS_main_ctl23_ctl00_ctl01" href="http://msdn.microsoft.com/en-us/library/kwdt6w2k.aspx">.NET Framework remoting</a> or <a id="ctl00_MTCS_main_ctl23_ctl00_ctl02" href="http://msdn.microsoft.com/en-us/library/7bkzywba.aspx">XML Web services</a> created using ASP.NET to use the processing time of other computers in addition to that of your own to increase responsiveness to the user and decrease the data processing time of your application.</div>
<div class="CollapseRegionLink"></div>
<div class="CollapseRegionLink">
<h3>Disadvantages of Multiple Threads</h3>
<div>
<p>It is recommended that you use as few threads as possible, thereby minimizing the use of operating-system resources and improving performance. Threading also has resource requirements and potential conflicts to be considered when designing your application. The resource requirements are as follows:</p>
<ul>
<li>The system consumes memory for the context information required by processes, <strong>AppDomain </strong>objects, and threads. Therefore, the number of processes, <strong>AppDomain </strong>objects, and threads that can be created is limited by available memory.</li>
<li>Keeping track of a large number of threads consumes significant processor time. If there are too many threads, most of them will not make significant progress. <span style="color:#ff0000;">If most of the current threads are in one process, threads in other processes are scheduled less frequently</span>.</li>
<li>Controlling code execution with many threads is complex, and can be a source of many bugs.</li>
<li>Destroying threads requires knowing what could happen and handling those issues.</li>
</ul>
</div>
</div>
<div class="CollapseRegionLink">
<p>Resources that require <span style="color:#ff0000;"><strong>synchronization </strong></span>include:</p>
<ul>
<li>System resources (such as communications ports).</li>
<li>Resources shared by multiple processes (such as file handles).</li>
<li>The resources of a single application domain (such as <strong><span style="color:#0000ff;">global, static, and instance fields</span></strong>) accessed by multiple threads.</li>
</ul>
</div>
<div class="CollapseRegionLink">
<h2>Synchronizing Data for Multithreading</h2>
<p><!--Content type: Devdiv1. Transform: orcas2mtps.xslt.--></p>
<div>
<p>When multiple threads can make calls to the properties and methods of a single object, it is critical that those calls be synchronized. Otherwise one thread might interrupt what another thread is doing, and the object could be left in an invalid state. A class whose members are protected from such interruptions is called thread-safe.</p>
<p>The Common Language Infrastructure provides several strategies to synchronize access to instance and static members:</p>
<ul>
<li>Synchronized code regions. You can use the <a id="ctl00_MTCS_main_ctl01" href="http://msdn.microsoft.com/en-us/library/system.threading.monitor.aspx">Monitor</a> class or compiler support for this class to synchronize only the code block that needs it, improving performance.</li>
<li>Manual synchronization.You can use the synchronization objects provided by the .NET Framework class library. See <a id="ctl00_MTCS_main_ctl02" href="http://msdn.microsoft.com/en-us/library/ms228964.aspx">Overview of Synchronization Primitives</a>, which includes a discussion of the <a id="ctl00_MTCS_main_ctl03" href="http://msdn.microsoft.com/en-us/library/system.threading.monitor.aspx">Monitor</a> class.</li>
<li>Synchronized contexts. You can use the <a id="ctl00_MTCS_main_ctl04" href="http://msdn.microsoft.com/en-us/library/system.runtime.remoting.contexts.synchronizationattribute.aspx">SynchronizationAttribute</a> to enable simple, automatic synchronization for <a id="ctl00_MTCS_main_ctl05" href="http://msdn.microsoft.com/en-us/library/system.contextboundobject.aspx">ContextBoundObject</a> objects.</li>
<li><a id="ctl00_MTCS_main_ctl06" href="http://msdn.microsoft.com/en-us/library/system.collections.hashtable.synchronized.aspx">Synchronized</a> property. A few classes, such as <a id="ctl00_MTCS_main_ctl07" href="http://msdn.microsoft.com/en-us/library/system.collections.hashtable.aspx">Hashtable</a> and <a id="ctl00_MTCS_main_ctl08" href="http://msdn.microsoft.com/en-us/library/system.collections.queue.aspx">Queue</a>, provide a <a id="ctl00_MTCS_main_ctl09" href="http://msdn.microsoft.com/en-us/library/system.collections.queue.synchronized.aspx">Synchronized</a> property that returns a thread-safe wrapper for an instance of the class. See <a id="ctl00_MTCS_main_ctl10" href="http://msdn.microsoft.com/en-us/library/573ths2x.aspx">Collections and Synchronization (Thread Safety)</a>.</li>
</ul>
<p>The common language runtime provides a thread model in which classes fall into a number of categories that can be synchronized in a variety of different ways depending on the requirements. The following table shows what synchronization support is provided for fields and methods with a given synchronization category.</p>
<div></div>
<div>
<table border="0">
<tbody>
<tr>
<th>Category</th>
<th>Global fields</th>
<th>Static fields</th>
<th>Static methods</th>
<th>Instance fields</th>
<th>Instance methods</th>
<th>Specific code blocks</th>
</tr>
<tr>
<td>No Synchronization</td>
<td>No</td>
<td>No</td>
<td>No</td>
<td>No</td>
<td>No</td>
<td>No</td>
</tr>
<tr>
<td>Synchronized Context</td>
<td>No</td>
<td>No</td>
<td>No</td>
<td>Yes</td>
<td>Yes</td>
<td>No</td>
</tr>
<tr>
<td>Synchronized Code Regions</td>
<td>No</td>
<td>No</td>
<td>Only if marked</td>
<td>No</td>
<td>Only if marked</td>
<td>Only if marked</td>
</tr>
<tr>
<td>Manual Synchronization</td>
<td>Manual</td>
<td>Manual</td>
<td>Manual</td>
<td>Manual</td>
<td>Manual</td>
<td>Manual</td>
</tr>
</tbody>
</table>
</div>
</div>
<div>
<div><!-- ApplyClick with current id --> <img style="vertical-align:middle;border-width:0;" src="http://i.msdn.microsoft.com/Global/Images/clear.gif" alt="" /></div>
</div>
</div>
<div class="CollapseRegionLink"></div>
<div class="CollapseRegionLink">
<h3>Threading and Application Design</h3>
<div>
<p>In general, using the <a id="ctl00_MTCS_main_ctl23_ctl00_ctl03" href="http://msdn.microsoft.com/en-us/library/system.threading.threadpool.aspx">ThreadPool</a> class is the easiest way to handle multiple threads for relatively short tasks that will not block other threads and when you do not expect any particular scheduling of the tasks. However, there are a number of reasons to create <span style="color:#ff0000;">your own threads</span>:</p>
<ul>
<li>If you need a task to have a particular <strong><span style="color:#0000ff;">priority</span></strong>.</li>
<li>If you have a task that might <span style="color:#0000ff;"><strong>run a long time</strong></span> (and therefore block other tasks).</li>
<li>If you need to place threads into a single-threaded apartment (all <strong>ThreadPool </strong>threads are in the multithreaded apartment).</li>
<li>If you need a stable identity associated with the thread. For example, you should use a dedicated thread to abort that thread, suspend it, or discover it by name.</li>
<li>If you need to run background threads that interact with the user interface, the .NET Framework version 2.0 provides a <a id="ctl00_MTCS_main_ctl23_ctl00_ctl04" href="http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx">BackgroundWorker</a> component that communicates using events, with cross-thread marshaling to the user-interface thread.</li>
</ul>
</div>
</div>
<div class="CollapseRegionLink"><span style="font-family:Verdana,Arial,Helvetica,sans-serif;"></p>
<h4>Apartment Threading (Single Threaded Apartment)</h4>
<p>Apartment threaded means there are multiple threads within the application. In single threaded apartment (STA) each thread is isolated in a separate apartment underneath the process. The process can have any number of apartments that share data through a proxy. The application defines when and for how long the thread in each apartment should execute. All requests are serialized through the Windows message queue such that only a single apartment is accessed at a time and thus only a single thread will be executing at any one time. STA is the threading model that most Visual Basic developers are familiar with because this is the threading model available to VB applications prior to VB.NET. You can think of it like an apartment building full of a row of one room apartments that are accessible one at a time through a single hallway. The advantage this provides over single threaded is that multiple commands can be issued at one time instead of just a single command, but the commands are still <span style="color:#ff0000;"><strong>sequentially executed</strong></span>.</p>
<h4>Free Threading (Multi Threaded Apartment)</h4>
<p>Free threaded applications were limited to programming languages such as C++ until the release of Microsoft .NET. The free threaded/Multi Threaded Apartment (MTA) model has a single apartment created underneath the process rather than multiple apartments. This single apartment holds multiple threads rather than just a single thread. No message queue is required because all of the threads are a part of the same apartment and <span style="color:#ff0000;"><strong>can share data without a proxy</strong></span>. You can think of it like a building with multiple rooms that are all accessible once you are inside the building. These applications typically execute faster than single threaded and STA because there is less system overhead and can be optimized to eliminate system idle time.</p>
<p>These types of applications are more complex to program. The developer must provide <span style="color:#ff0000;"><strong>thread synchronization</strong></span> as part of the code to ensure that threads do not simultaneously access the same resources. A condition known as a <span style="color:#ff0000;"><strong>race condition</strong></span> can occur when a thread accesses a shared resource and modifies the resource to an invalid state and then another thread accesses the shared resource and uses it in the invalid state before the other thread can return the resource to a valid state. Therefore it is necessary to place a lock on a resource to prevent other threads from accessing the resource until the lock has been removed. However, this can lead to a <span style="color:#ff0000;"><strong>deadlock </strong></span>situation where two threads are competing for resources and neither can proceed.</p>
<p>The only way to avoid situations like these is through good design and testing.</p>
<p></span></div>
<div class="CollapseRegionLink">
<p>Rules for <span style="color:#ff0000;"><strong>single-threaded apartments</strong></span> are simple, but it is important to follow them carefully:</p>
<ul>
<li> Every object should live on only one thread (within a single-threaded apartment).</li>
<li> Initialize the COM library for each thread.</li>
<li> Marshal all pointers to objects when passing them between apartments.</li>
<li> Each single-threaded apartment must have a message loop to handle calls from other processes and apartments within the same process. Single-threaded apartments without objects (client only) also need a message loop to dispatch the broadcast messages that some applications use.</li>
<li>DLL-based or in-process objects do not call the COM initialization functions; instead, they register their threading model with the <strong>ThreadingModel</strong> named-value under the <a id="ctl00_MTCS_main_ctl01" href="http://msdn.microsoft.com/en-us/library/ms682390%28VS.85%29.aspx">InprocServer32</a> key in the registry. Apartment-aware objects must also write DLL entry points carefully. There are special considerations that apply to threading in-process servers. For more information, see <a id="ctl00_MTCS_main_ctl02" href="http://msdn.microsoft.com/en-us/library/ms687205%28VS.85%29.aspx">In-Process Server Threading Issues</a>.</li>
</ul>
</div>
<div class="CollapseRegionLink">
<p>Following are some important considerations regarding <span style="color:#ff0000;"><strong>synchronization for multithreaded apartments</strong></span>:</p>
<ul>
<li> COM provides call synchronization for single-threaded apartments only.</li>
<li> Multithreaded apartments do not receive calls while making calls (on the same thread).</li>
<li> Multithreaded apartments cannot make input-synchronized calls.</li>
<li> Asynchronous calls are converted to synchronous calls in multithreaded apartments.</li>
<li> The message filter is not called for any thread in a multithreaded apartment.</li>
</ul>
</div>
<div class="CollapseRegionLink">
<div>
<table border="0">
<tbody>
<tr>
<th><!--src=[../icons/alert_caution.gif]--><img src="http://i.msdn.microsoft.com/z8chs7ft.alert_caution%28en-us,VS.90%29.gif" alt="Important note" /><strong>Important Note:</strong></th>
</tr>
<tr>
<td>Do not lock the type — that is, <span style="color:#0000ff;">typeof(MyType)</span> in C#, GetType(MyType) in Visual Basic, or <span style="color:#0000ff;">MyType::typeid</span> in C++ — in order to protect <span style="color:#ff0000;"><strong>static </strong></span>methods (Shared methods in Visual Basic). Use a <span style="color:#0000ff;"><strong>private static object i</strong></span>nstead. Similarly, do not use<span style="color:#0000ff;"><strong> this</strong></span> in C# (Me in Visual Basic) to lock instance methods. Use a private object instead. A class or instance<span style="color:#ff0000;"><strong> can be locked by code other than your own</strong></span>, potentially causing deadlocks or performance problems.</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="CollapseRegionLink">
<h3>Synchronized Context</h3>
<div style="display:block;"><a id="sectionToggle3"></a>You can use the <strong>SynchronizationAttribute </strong>on any <strong>ContextBoundObject </strong>to synchronize all instance methods and fields. All objects in the same context domain share the same lock. Multiple threads are allowed to access the methods and fields, but only a single thread is allowed at any one time.</p>
</div>
</div>
<div class="CollapseRegionLink"></div>
<div class="CollapseRegionLink"><strong>Setting Up for a Background Operation </strong></div>
<div class="MTPS_CollapsibleSection" style="display:block;"><a id="sectionToggle1"></a>To set up for a background operation, add an event handler for the <a id="ctl00_MTCS_main_ctl59_ctl00_ctl00" href="http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.dowork.aspx">DoWork</a> event. Call your time-consuming operation in this event handler.To start the operation, call <a id="ctl00_MTCS_main_ctl59_ctl00_ctl01" href="http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.runworkerasync.aspx">RunWorkerAsync</a>. To receive notifications of progress updates, handle the <a id="ctl00_MTCS_main_ctl59_ctl00_ctl02" href="http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.progresschanged.aspx">ProgressChanged</a> event. To receive a notification when the operation is completed, handle the <a id="ctl00_MTCS_main_ctl59_ctl00_ctl03" href="http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.runworkercompleted.aspx">RunWorkerCompleted</a> event.The methods that handle the <a id="ctl00_MTCS_main_ctl59_ctl00_ctl04" href="http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.progresschanged.aspx">ProgressChanged</a> and <a id="ctl00_MTCS_main_ctl59_ctl00_ctl05" href="http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.runworkercompleted.aspx">RunWorkerCompleted</a> events can access the application&#8217;s user interface, because those events are raised on the thread that called the <a id="ctl00_MTCS_main_ctl59_ctl00_ctl06" href="http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.runworkerasync.aspx">RunWorkerAsync</a> method. However, the <a id="ctl00_MTCS_main_ctl59_ctl00_ctl07" href="http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.dowork.aspx">DoWork</a> event handler cannot work with any user-interface objects because it runs on the background thread.</p>
</div>
</div>
<div class="MTPS_CollapsibleRegion">
<div class="CollapseRegionLink"><!-- ApplyClick with current id --> <strong> Creating and Using Threads </strong></div>
<div class="MTPS_CollapsibleSection" style="display:block;"><a id="sectionToggle2"></a>If you need more control over the behavior of your application&#8217;s threads, you can manage the threads yourself. However, realize that writing correct multithreaded applications can be difficult: Your application may stop responding or experience transient errors caused by race conditions. For more information, see <a id="ctl00_MTCS_main_ctl60_ctl00_ctl00" href="http://msdn.microsoft.com/en-us/library/a8544e2s.aspx">Thread-Safe Components</a>.You create a new thread in Visual Basic by declaring a variable of type <a id="ctl00_MTCS_main_ctl60_ctl00_ctl01" href="http://msdn.microsoft.com/en-us/library/system.threading.thread.aspx">Thread</a> and calling the constructor with the <span class="input">AddressOf</span> statement and the name of the procedure or method that you want to execute on the new thread.</div>
</div>
<h3 class="subHeading">Safe Points</h3>
<div class="subsection">
<p>Most of these methods are self-explanatory, but the concept of <span class="parameter">safe points</span> may be new to you. Safe points are locations in code where it is safe for the common language runtime to perform automatic <span class="parameter">garbage collection</span>, the process of releasing unused variables and reclaiming memory. When you call the <a id="ctl00_MTCS_main_ctl60_ctl00_ctl18" href="http://msdn.microsoft.com/en-us/library/system.threading.thread.abort.aspx">Abort</a> or <a id="ctl00_MTCS_main_ctl60_ctl00_ctl19" href="http://msdn.microsoft.com/en-us/library/system.threading.thread.suspend.aspx">Suspend</a> method of a thread, the common language runtime analyzes the code and determines the location of an appropriate location for the thread to stop running.</p>
</div>
<p><a href="http://msdn.microsoft.com/en-us/library/ck8bc5c6.aspx">Multithreaded Applications</a>.</p>
<p>You can provide parameters and return values to thread-pool threads by using the optional <span class="input">ByVal</span> state-object variable of the <a id="ctl00_MTCS_main_ctl21_ctl00_ctl02" href="http://msdn.microsoft.com/en-us/library/system.threading.threadpool.queueuserworkitem.aspx">QueueUserWorkItem</a> method. Thread-timer threads also support a state object for this purpose. For information on thread pooling and thread timers, see <a id="ctl00_MTCS_main_ctl21_ctl00_ctl03" href="http://msdn.microsoft.com/en-us/library/h4732ks0.aspx">Thread Pooling</a> and <a id="ctl00_MTCS_main_ctl21_ctl00_ctl04" href="http://msdn.microsoft.com/en-us/library/swx5easy.aspx">Thread Timers</a>.</p>
<div class="CollapseRegionLink"><strong><a href="http://msdn.microsoft.com/en-us/library/0ka9477y.aspx">Thread Pooling</a> Example </strong></div>
<div class="MTPS_CollapsibleSection" style="display:block;"><a id="sectionToggle0"></a>The following example shows how you can use thread pooling to start several tasks.</p>
<div id="snippetGroup"><span id="ctl00_MTCS_main_ctl17_ctl00_ctl00"></p>
<div id="ctl00_MTCS_main_ctl17_ctl00_ctl00_VisualBasic" class="libCScode">
<div class="CodeSnippetTitleBar">
<div class="CodeDisplayLanguage">Visual Basic</div>
</div>
<div style="background-color:#dddddd;" dir="ltr">
<pre class="libCScode" style="white-space:pre-wrap;"><span style="color:blue;">Sub</span> DoWork()
    <span style="color:green;">' Queue a task</span>
    System.Threading.ThreadPool.QueueUserWorkItem( _
        <span style="color:blue;">New</span> System.Threading.WaitCallback(<span style="color:blue;">AddressOf</span> SomeLongTask))
    <span style="color:green;">' Queue another task</span>
    System.Threading.ThreadPool.QueueUserWorkItem( _
        <span style="color:blue;">New</span> System.Threading.WaitCallback(<span style="color:blue;">AddressOf</span> AnotherLongTask))
<span style="color:blue;">End</span> <span style="color:blue;">Sub</span>
<span style="color:blue;">Sub</span> SomeLongTask(<span style="color:blue;">ByVal</span> state <span style="color:blue;">As</span> <span style="color:blue;">Object</span>)
    <span style="color:green;">' Insert code to perform a long task.</span>
<span style="color:blue;">End</span> <span style="color:blue;">Sub</span>
<span style="color:blue;">Sub</span> AnotherLongTask(<span style="color:blue;">ByVal</span> state <span style="color:blue;">As</span> <span style="color:blue;">Object</span>)
    <span style="color:green;">' Insert code to perform another long task.</span>
<span style="color:blue;">End</span> <span style="color:blue;">Sub</span></pre>
</div>
</div>
<p></span></div>
<p>Thread pooling is useful when you want to start many separate tasks without individually setting the properties of each thread. Each thread starts with a default stack size and priority. By default, up to 25 thread-pool threads can run per system processor. Additional threads in excess of the limit can be queued, but they do not start until other threads finish.</p>
<p>One advantage of thread pooling is that you can pass arguments in a state object to the task procedure. If the procedure you are calling requires more than one argument, you can cast a structure or an instance of a class into an <span class="input">Object</span> data type.</p>
</div>
<h2><strong><a href="http://msdn.microsoft.com/en-us/library/a60kkx8k.aspx">Application Domains and Threads</a></strong>.</h2>
<div>
<p>An application domain forms an isolation boundary for security, versioning, reliability, and unloading of managed code. Threads are the operating system construct used by the common language runtime to execute code. At run time, all managed code is loaded into an application domain and is run by a managed thread.</p>
<p>There is not a one-to-one correlation between application domains and threads. Several threads can be executing in a single application domain at any given time and a particular thread is not confined to a single application domain. That is, threads are free to cross application domain boundaries; a new thread is not created for each application domain.</p>
<p>At any given time, every thread is executing in an application domain. Zero, one, or more than one thread might be executing in any given application domain. The run time keeps track of which threads are running in which application domains. You can locate the domain in which a thread is executing at any time by calling the <a id="ctl00_MTCS_main_ctl01" href="http://msdn.microsoft.com/en-us/library/system.threading.thread.getdomain.aspx">GetDomain</a> method.</p>
</div>
<div class="MTPS_CollapsibleRegion">
<div class="MTPS_CollapsibleSection" style="display:block;">
<h2><strong><a href="http://msdn.microsoft.com/en-us/library/awbftdfh(VS.80).aspx">Events (C#)</a>.</strong></h2>
<p>Events can be used to <strong>synchronize threads</strong>.</p>
<p><strong>Delegate </strong>is a creatable type. Programming with delegates requires creating delegate objects from delegate types.</p>
<p>Delegates seamlessly support binding a notification source to multiple handler methods through a feature known as <strong>multicasting</strong>.</p>
<p>Delegate binding, see <a id="ctl00_MTCS_main_ctl35_ctl00_ctl01" href="http://msdn.microsoft.com/en-us/library/96b1ayy4%28VS.80%29.aspx">Delegates in the Common Type System</a> and <a id="ctl00_MTCS_main_ctl35_ctl00_ctl02" href="http://msdn.microsoft.com/en-us/library/s3860fy3%28VS.80%29.aspx">CreateDelegate(Type,Object,MethodInfo,Boolean)</a>.</p>
<p>Delegates are referred to as</p>
<ul>
<li>multicast, or</li>
<li>combinable,</li>
</ul>
<p>because a delegate can invoke one or more methods and can be used in combining operations.A delegate can represent a</p>
<ul>
<li>static method or</li>
<li>an instance method.</li>
</ul>
<div class="MTPS_CollapsibleSection" style="display:block;">When the delegate represents an instance method, the delegate stores not only a reference to the method&#8217;s entry point, but also a reference to the class instance. Unlike <strong>function pointers</strong>,</div>
<ul>
<li>delegates are object oriented and</li>
<li>type safe.</li>
</ul>
<p><a id="ctl00_MTCS_main_ctl06" href="http://msdn.microsoft.com/en-us/library/ms366768%28VS.80%29.aspx">How to: Subscribe to and Unsubscribe from Events (C# Programming Guide)</a></p>
<p>The line of code that is needed to subscribe to the event is also automatically generated in the <tt>InitializeComponent</tt> method in the Form1.Designer.cs file in your project. It looks like this:</p>
<p><span id="ctl00_MTCS_main_ctl02"> </span></p>
<div id="ctl00_MTCS_main_ctl02_">
<div style="background-color:#dddddd;" dir="ltr">
<pre style="white-space:pre-wrap;">  this.Load += new System.EventHandler(this.Form1_Load);</pre>
</div>
</div>
<h3>To subscribe to events programmatically</h3>
<div>
<ol>
<li>Define an event handler method whose signature matches the delegate signature for the event. For example, if the event is based on the <a id="ctl00_MTCS_main_ctl03" href="http://msdn.microsoft.com/en-us/library/system.eventhandler%28VS.80%29.aspx">EventHandler</a> delegate type, then the following code represents the method stub:<span id="ctl00_MTCS_main_ctl04"> </span>
<div id="ctl00_MTCS_main_ctl04_">
<div style="background-color:#dddddd;" dir="ltr">
<pre style="white-space:pre-wrap;">  void HandleCustomEvent(object sender, CustomEventArgs a)
  {
     // Do something useful here.
  }</pre>
</div>
</div>
</li>
<li>Use the addition assignment operator (+=) to attach your event handler to the event. In the following example, assume that an object named <tt>publisher</tt> has an event named <tt>RaiseCustomEvent</tt>. Note that the subscriber class needs a reference to the publisher class in order to subscribe to its events.<span id="ctl00_MTCS_main_ctl05"> </span>
<div id="ctl00_MTCS_main_ctl05_">
<div style="background-color:#dddddd;" dir="ltr">
<pre style="white-space:pre-wrap;">publisher.RaiseCustomEvent += HandleCustomEvent;</pre>
</div>
</div>
</li>
</ol>
<p>Note that the above syntax is new in C# 2.0. It is exactly equivalent to the C# 1.0 syntax in which the encapsulating delegate must be explicitly created using the new keyword:</p>
<p><span id="ctl00_MTCS_main_ctl06"> </span></p>
<div id="ctl00_MTCS_main_ctl06_">
<div style="background-color:#dddddd;" dir="ltr">
<pre style="white-space:pre-wrap;">publisher.RaiseCustomEvent += new CustomEventHandler(HandleCustomEvent);</pre>
</div>
</div>
</div>
<h3>To subscribe to events by using an anonymous method</h3>
<div>
<ul>
<li>Use the addition assignment operator (+=) to attach your anonymous method to the event. In the following example, assume that an object named <tt>publisher</tt> has an event named <tt>RaiseCustomEvent </tt>and that a <tt>CustomEventArgs</tt> class has also been defined to carry some kind of specialized event information. Note that the subscriber class needs a reference to <tt>publisher</tt> in order to subscribe to its events.<span id="ctl00_MTCS_main_ctl07"> </span>
<div id="ctl00_MTCS_main_ctl07_">
<div style="background-color:#dddddd;" dir="ltr">
<pre style="white-space:pre-wrap;">  publisher.RaiseCustomEvent += delegate(object o, CustomEventArgs e)
  {
    string s = o.ToString() + " " + e.ToString();
    Console.WriteLine(s);
  };</pre>
</div>
</div>
</li>
</ul>
<p>It is important to note that you cannot easily unsubscribe from an event if you used an anonymous method to subscribe to it. To unsubscribe in this scenario, go back to the code where you subscribe to the event, store the anonymous method in a delegate variable, and then add the delegate to the event.</p>
<p>When an event has multiple subscribers, the event handlers are invoked synchronously when an event is raised. To invoke events asynchronously, see <strong><a id="ctl00_MTCS_main_ctl03" href="http://msdn.microsoft.com/en-us/library/2e08f6yc%28VS.80%29.aspx">Calling Synchronous Methods Asynchronously</a></strong>.</p>
<p>four common ways to use <strong>BeginInvoke</strong> and <strong>EndInvoke</strong> to make asynchronous calls. After calling <strong>BeginInvoke</strong> you can do the following:</p>
<ul>
<li>Do some work and then call <strong>EndInvoke</strong> to block until the call completes.</li>
<li>Obtain a <a id="ctl00_MTCS_main_ctl05" href="http://msdn.microsoft.com/en-us/library/system.threading.waithandle%28VS.80%29.aspx">WaitHandle</a> using the <a id="ctl00_MTCS_main_ctl06" href="http://msdn.microsoft.com/en-us/library/system.iasyncresult.asyncwaithandle%28VS.80%29.aspx">System.IAsyncResult.AsyncWaitHandle</a> property, use its <a id="ctl00_MTCS_main_ctl07" href="http://msdn.microsoft.com/en-us/library/system.threading.waithandle.waitone%28VS.80%29.aspx">WaitOne</a> method to block execution until the <strong>WaitHandle</strong> is signaled, and then call <strong>EndInvoke</strong>.</li>
<li>Poll the <strong>IAsyncResult</strong> returned by <strong>BeginInvoke</strong> to determine when the asynchronous call has completed, and then call <strong>EndInvoke</strong>.</li>
<li>Pass a delegate for a callback method to <strong>BeginInvoke</strong>. The method is executed on a <a id="ctl00_MTCS_main_ctl08" href="http://msdn.microsoft.com/en-us/library/system.threading.threadpool%28VS.80%29.aspx">ThreadPool</a> thread when the asynchronous call completes. The callback method calls <strong>EndInvoke</strong>.
<div>
<table border="0" width="100%">
<tbody>
<tr>
<th align="left"><img src="http://i.msdn.microsoft.com/2e08f6yc.note%28en-US,VS.80%29.gif" alt="Note" />Important</th>
</tr>
<tr>
<td>Always call <strong>EndInvoke</strong> to complete your asynchronous call.</td>
</tr>
</tbody>
</table>
</div>
</li>
</ul>
<p>you should know that events in the .NET Framework are layered on top of delegates. When you use an event-driven application framework such as Windows® Forms or ASP.NET, your knowledge of delegates will make you a much stronger developer.</p>
<blockquote><p>Delegates provide the primary means in .NET for executing a method on a secondary thread in an asynchronous fashion. Therefore, delegates open the door to <strong>multithreading</strong>.</p></blockquote>
</div>
<p>the compiler generates a class definition for each delegate type. The class that is generated for each delegate type is a creatable class that inherits from the <strong>System.Multicast </strong>delegate.</p>
<p>compiler has also added a public constructor and three public methods named</p>
<ul>
<li>Invoke,</li>
<li>BeginInvoke, and</li>
<li>EndInvoke.</li>
</ul>
<h2><strong><a id="ctl00_MTCS_main_ctl21" href="http://msdn.microsoft.com/en-us/library/ms228969%28VS.80%29.aspx">Asynchronous Programming Design Patterns</a></strong></h2>
<p>Asynchronous operations are typically used to perform tasks that might take a long time to complete, such as opening large files, connecting to remote computers, or querying a database. An asynchronous operation executes in a thread separate from the main application thread. When an application calls methods to perform an operation asynchronously, the application can continue executing while the asynchronous method performs its task.</p>
<p>Asynchronous programming is a feature supported by many areas of the <strong>.NET Framework</strong>, including:</p>
<ul>
<li>File IO, Stream IO, Socket IO.</li>
<li>Networking.</li>
<li>Remoting channels (HTTP, TCP) and proxies.</li>
<li>XML Web services created using ASP.NET.</li>
<li>ASP.NET Web Forms.</li>
<li>Message Queuing using the <a id="ctl00_MTCS_main_ctl03" href="http://msdn.microsoft.com/en-us/library/system.messaging.messagequeue%28VS.80%29.aspx">MessageQueue</a> class.</li>
</ul>
<p>The .NET Framework provides two design patterns for asynchronous operations:</p>
<ul>
<li>Asynchronous operations that use <a id="ctl00_MTCS_main_ctl01" href="http://msdn.microsoft.com/en-us/library/system.iasyncresult%28VS.80%29.aspx">IAsyncResult</a> objects.</li>
<li>Asynchronous operations that use events. <a id="ctl00_MTCS_main_ctl02" href="http://msdn.microsoft.com/en-us/library/wewwczdw%28VS.80%29.aspx">Event-based Asynchronous Pattern Overview</a>.</li>
</ul>
<p>For relatively simple multithreaded applications, the <a id="ctl00_MTCS_main_ctl02" href="http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker%28VS.80%29.aspx">BackgroundWorker</a> component provides a straightforward solution. For more sophisticated asynchronous applications, consider implementing a class that adheres to the Event-based Asynchronous Pattern.
<dl>
<dt><strong><a id="ctl00_MTCS_main_ctl04" href="http://msdn.microsoft.com/en-us/library/ms228963%28VS.80%29.aspx">Asynchronous Programming Overview</a></strong></dt>
<dd>Discusses the <strong>IAsyncResult</strong> based asynchronous design pattern, which provides a flexible programming model to deal with asynchronous operations. </dd>
</dl>
<p>The correct choice depends on whether the application has instructions that can execute while the operation completes. If an application cannot perform any additional work until it receives the results of the asynchronous operation, the application must block until the results are available. <strong>To block until an asynchronous operation completes</strong>, you can use one of the following approaches:</p>
<ul>
<li>Call <strong>End</strong><em>OperationName</em> from the application’s main thread, blocking application execution until the operation is complete. For an example that illustrates this technique, see <a id="ctl00_MTCS_main_ctl16" href="http://msdn.microsoft.com/en-us/library/ms228967%28VS.80%29.aspx">Blocking Application Execution by Ending an Asynchronous Operation</a>.</li>
<li>Use the <strong>AsyncWaitHandle</strong> to block application execution until one or more operations are complete. For an example that illustrates this technique, see <a id="ctl00_MTCS_main_ctl17" href="http://msdn.microsoft.com/en-us/library/ms228962%28VS.80%29.aspx">Blocking Application Execution Using an AsyncWaitHandle</a>.</li>
</ul>
<p>Applications that do <strong>not </strong>need to block while the asynchronous operation completes can use one of the following approaches:</p>
<ul>
<li>Poll for operation completion status by checking the <strong>IsCompleted</strong> property periodically and calling <strong>End</strong><em>OperationName</em> when the operation is complete. For an example that illustrates this technique, see <a id="ctl00_MTCS_main_ctl18" href="http://msdn.microsoft.com/en-us/library/ms228968%28VS.80%29.aspx">Polling for the Status of an Asynchronous Operation</a>.</li>
<li>Use an <strong>AsyncCallback</strong> delegate to specify a method to be invoked when the operation is complete. For an example that illustrates this technique, see <a id="ctl00_MTCS_main_ctl19" href="http://msdn.microsoft.com/en-us/library/ms228972%28VS.80%29.aspx">Using an AsyncCallback Delegate to End an Asynchronous Operation</a>.</li>
</ul>
<p><a id="ctl00_MTCS_main_ctl18" href="http://msdn.microsoft.com/en-us/library/dacysss4%28VS.80%29.aspx">Creating Event Handlers in Windows Forms</a></p>
<ul>
<li><a id="ctl00_MTCS_main_ctl06" href="http://msdn.microsoft.com/en-us/library/ms366768%28VS.80%29.aspx">How to: Subscribe to and Unsubscribe from Events (C# Programming Guide)</a></li>
<li><a id="ctl00_MTCS_main_ctl07" href="http://msdn.microsoft.com/en-us/library/w369ty8x%28VS.80%29.aspx">How to: Publish Events that Conform to .NET Framework Guidelines (C# Programming Guide)</a></li>
<li><a id="ctl00_MTCS_main_ctl08" href="http://msdn.microsoft.com/en-us/library/hy3sefw3%28VS.80%29.aspx">How to: Raise Base Class Events in Derived Classes (C# Programming Guide)</a></li>
<li><a id="ctl00_MTCS_main_ctl09" href="http://msdn.microsoft.com/en-us/library/ak9w5846%28VS.80%29.aspx">How to: Implement Interface Events (C# Programming Guide)</a></li>
<li><a id="ctl00_MTCS_main_ctl10" href="http://msdn.microsoft.com/en-us/library/ms173179%28VS.80%29.aspx">Thread Synchronization (C# Programming Guide)</a></li>
<li><a id="ctl00_MTCS_main_ctl11" href="http://msdn.microsoft.com/en-us/library/z4ka55h8%28VS.80%29.aspx">How to: Use a Dictionary to Store Event Instances (C# Programming Guide)</a></li>
<li><a id="ctl00_MTCS_main_ctl12" href="http://msdn.microsoft.com/en-us/library/y4592h76%28VS.80%29.aspx">Events Sample</a></li>
<li><a id="ctl00_MTCS_main_ctl13" href="http://msdn.microsoft.com/en-us/library/ms229011%28VS.80%29.aspx">Event Design</a></li>
</ul>
<p><a id="ctl00_MTCS_main_ctl16" href="http://msdn.microsoft.com/en-us/library/3es4b6yy%28VS.80%29.aspx">Multithreading in Components</a></p>
<p><a id="ctl00_MTCS_main_ctl14" href="http://msdn.microsoft.com/en-us/library/1c9txz50%28VS.80%29.aspx">Managed Threading Best Practices</a></p>
<dl>
<dt><a id="ctl00_MTCS_main_ctl02" href="http://msdn.microsoft.com/en-us/library/e7a34yad%28VS.80%29.aspx">Implementing the Event-based Asynchronous Pattern</a></dt>
<dd>Describes the standardized way to package a class that has asynchronous features. </dd>
</dl>
<p>features of the <strong>Event-based Asynchronous Pattern</strong> discussed in this topic.</p>
<ul>
<li>Opportunities for Implementing the Event-based Asynchronous Pattern</li>
<li>Naming Asynchronous Methods</li>
<li>Optionally Support Cancellation</li>
<li>Optionally Support the IsBusy Property</li>
<li>Optionally Provide Support for Progress Reporting</li>
<li>Optionally Provide Support for Returning Incremental Results</li>
<li>Handling Out and Ref Parameters in Methods</li>
</ul>
<dl>
<dt><a id="ctl00_MTCS_main_ctl04" href="http://msdn.microsoft.com/en-us/library/ms228966%28VS.80%29.aspx">Deciding When to Implement the Event-based Asynchronous Pattern</a></dt>
<dd>Describes how to determine when you should choose to implement the Event-based Asynchronous Pattern instead of the <a id="ctl00_MTCS_main_ctl05" href="http://msdn.microsoft.com/en-us/library/system.iasyncresult%28VS.80%29.aspx">IAsyncResult</a> pattern. </dd>
</dl>
<dl>
<dt><a id="ctl00_MTCS_main_ctl12" href="http://msdn.microsoft.com/en-us/library/khfcee8y%28VS.80%29.aspx">Event-based Asynchronous Pattern Technology Sample</a></dt>
<dd>Shows how to use the Event-based Asynchronous Pattern to perform common asynchronous operations. </dd>
</dl>
<p><a id="ctl00_MTCS_main_ctl15" href="http://msdn.microsoft.com/en-us/library/17sde2xt%28VS.80%29.aspx">Events and Delegates</a></p>
<p><strong><a id="ctl00_MTCS_main_ctl16" href="http://msdn.microsoft.com/en-us/library/hybbz6ke%28VS.80%29.aspx">How to: Run an Operation in the Background</a></strong></p>
<p>use the <a id="ctl00_MTCS_main_ctl02" href="http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker%28VS.80%29.aspx">BackgroundWorker</a> class to run the operation on another thread.</p>
<p><span id="ctl00_MTCS_main_ctl10"> </span></p>
<h1>Robust Programming</h1>
<div id="robustProgrammingSection">
<div>
<table border="0" width="100%">
<tbody>
<tr>
<th align="left"><img src="http://i.msdn.microsoft.com/waw3xexc.Caution%28en-US,VS.80%29.gif" alt="Caution note" />Caution</th>
</tr>
<tr>
<td>When using multithreading of any sort, you potentially expose yourself to very serious and complex bugs. Consult the <a id="ctl00_MTCS_main_ctl12" href="http://msdn.microsoft.com/en-us/library/1c9txz50%28VS.80%29.aspx">Managed Threading Best Practices</a> before implementing any solution that uses multithreading.</td>
</tr>
</tbody>
</table>
</div>
</div>
<h3>Deadlocks</h3>
<p>A deadlock occurs when each of two threads tries to lock a resource the other has already locked. Neither thread can make any further progress.</p>
<p>Many methods of the managed threading classes provide time-outs to help you detect deadlocks. For example, the following code attempts to acquire a lock on the current instance. If the lock is not obtained in 300 milliseconds, <a id="ctl00_MTCS_main_ctl01" href="http://msdn.microsoft.com/en-us/library/system.threading.monitor.tryenter%28VS.80%29.aspx">Monitor.TryEnter</a> returns <strong>false</strong>.</p>
<h3>Race Conditions</h3>
<div>
<p>A race condition is a bug that occurs when the outcome of a program depends on which of two or more threads reaches a particular block of code first. Running the program many times produces different results, and the result of any given run cannot be predicted.</p>
<p>A simple example of a race condition is incrementing a field. Suppose a class has a private <strong>static</strong> field (<strong>Shared</strong> in Visual Basic) that is incremented every time an instance of the class is created, using code such as <tt>objCt++;</tt> (C#) or <tt>objCt += 1</tt> (Visual Basic). This operation requires loading the value from <tt>objCt</tt> into a register, incrementing the value, and storing it in <tt>objCt</tt>.</p>
<p>In a multithreaded application, a thread that has loaded and incremented the value might be preempted by another thread which performs all three steps; when the first thread resumes execution and stores its value, it overwrites <tt>objCt</tt> without taking into account the fact that the value has changed in the interim.</p>
<p>This particular race condition is easily avoided by using methods of the <a id="ctl00_MTCS_main_ctl04" href="http://msdn.microsoft.com/en-us/library/system.threading.interlocked%28VS.80%29.aspx">Interlocked</a> class, such as <a id="ctl00_MTCS_main_ctl05" href="http://msdn.microsoft.com/en-us/library/system.threading.interlocked.increment%28VS.80%29.aspx">Interlocked.Increment</a>. To read about other techniques for synchronizing data among multiple threads, see <a id="ctl00_MTCS_main_ctl06" href="http://msdn.microsoft.com/en-us/library/z8chs7ft%28VS.80%29.aspx">Synchronizing Data for Multithreading</a>.</p>
<p>Race conditions can also occur when you synchronize the activities of multiple threads. Whenever you write a line of code, you must consider what might happen if a thread were preempted before executing the line (or before any of the individual machine instructions that make up the line), and another thread overtook it.</p>
<p><a id="ctl00_MTCS_main_ctl54_ctl00_ctl01" href="http://msdn.microsoft.com/en-us/library/ms228964.aspx">Overview of Synchronization Primitives</a></p>
<p>The .NET Framework provides a range of synchronization primitives for controlling the interactions of threads and avoiding race conditions. These can be roughly divided into three categories:</p>
<ul>
<li>locking,</li>
<li>signaling, and</li>
<li>interlocked operations.</li>
</ul>
<p>The categories are not tidy and clearly defined: some synchronization mechanisms have characteristics of multiple categories; events that release a single thread at a time are functionally like locks; the release of any lock can be thought of as a signal; and interlocked operations can be used to construct locks. However, the categories are still useful.</p>
<h3>Signaling</h3>
<p><a id="sectionToggle1"></a>The simplest way to wait for a signal from another thread is to call the <a id="ctl00_MTCS_main_ctl100_ctl00_ctl00" href="http://msdn.microsoft.com/en-us/library/system.threading.thread.join.aspx">Join</a> method, which blocks until the other thread completes. <a id="ctl00_MTCS_main_ctl100_ctl00_ctl01" href="http://msdn.microsoft.com/en-us/library/system.threading.thread.join.aspx">Join</a> has two overloads that allow the blocked thread to break out of the wait after a specified interval has elapsed.</p>
<p>Wait handles provide a much richer set of waiting and signaling capabilities.</p>
<h3>Wait Handles</h3>
<div>
<p>Wait handles derive from the <a id="ctl00_MTCS_main_ctl100_ctl00_ctl02" href="http://msdn.microsoft.com/en-us/library/system.threading.waithandle.aspx">WaitHandle</a> class, which in turn derives from <a id="ctl00_MTCS_main_ctl100_ctl00_ctl03" href="http://msdn.microsoft.com/en-us/library/system.marshalbyrefobject.aspx">MarshalByRefObject</a>. Thus, wait handles can be used to synchronize the activities of threads across application domain boundaries.</p>
<p>Threads block on wait handles by calling the instance method <a id="ctl00_MTCS_main_ctl100_ctl00_ctl04" href="http://msdn.microsoft.com/en-us/library/system.threading.waithandle.waitone.aspx">WaitOne</a> or one of the static methods <a id="ctl00_MTCS_main_ctl100_ctl00_ctl05" href="http://msdn.microsoft.com/en-us/library/system.threading.waithandle.waitall.aspx">WaitAll</a>, <a id="ctl00_MTCS_main_ctl100_ctl00_ctl06" href="http://msdn.microsoft.com/en-us/library/system.threading.waithandle.waitany.aspx">WaitAny</a>, or <a id="ctl00_MTCS_main_ctl100_ctl00_ctl07" href="http://msdn.microsoft.com/en-us/library/system.threading.waithandle.signalandwait.aspx">SignalAndWait</a>. How they are released depends on which method was called, and on the kind of wait handles.</p>
<p>For a conceptual overview, see <a id="ctl00_MTCS_main_ctl100_ctl00_ctl08" href="http://msdn.microsoft.com/en-us/library/kad9xah9.aspx">Wait Handles</a>. Also <a id="ctl00_MTCS_main_ctl100_ctl00_ctl19" href="http://msdn.microsoft.com/en-us/library/ksb7zs2x.aspx">EventWaitHandle, AutoResetEvent, and ManualResetEvent</a>.</p>
<h3>Interlocked Operations</h3>
<div style="display:block;"><a id="sectionToggle2"></a>Interlocked operations are simple atomic operations performed on a memory location by static methods of the <a id="ctl00_MTCS_main_ctl101_ctl00_ctl00" href="http://msdn.microsoft.com/en-us/library/system.threading.interlocked.aspx">Interlocked</a> class. Those atomic operations include addition, increment and decrement, exchange, conditional exchange depending on a comparison, and read operations for 64-bit values on 32-bit platforms.</p>
<div>
<table border="0">
<tbody>
<tr>
<th><!--src=[../icons/alert_note.gif]--><img src="http://i.msdn.microsoft.com/ms228964.alert_note%28en-us,VS.90%29.gif" alt="Note" /><strong>Note:</strong></th>
</tr>
<tr>
<td>The guarantee of atomicity is limited to individual operations; when multiple operations must be performed as a unit, a more coarse-grained synchronization mechanism must be used.</td>
</tr>
</tbody>
</table>
</div>
<p>Although none of these operations are locks or signals, they can be used to construct locks and signals. Because they are native to the Windows operating system, interlocked operations are extremely fast.</p>
<p>Interlocked operations can be used with volatile memory guarantees to write applications which exhibit powerful non-blocking concurrency, however they require sophisticated, low level programming, and for most purposes simple locks are a better choice.</p>
<p>For a conceptual overview, see <a id="ctl00_MTCS_main_ctl101_ctl00_ctl02" href="http://msdn.microsoft.com/en-us/library/sbhbke0y.aspx">Interlocked Operations</a>.</p>
</div>
</div>
<h2><a id="ctl00_MTCS_main_ctl54_ctl00_ctl04" href="http://msdn.microsoft.com/en-us/library/system.runtime.remoting.contexts.synchronizationattribute.aspx">SynchronizationAttribute</a></h2>
<p>When this attribute is applied to an object, only one thread can be executing in all contexts that share an instance of this property. This is done by contributing sinks that intercept and serialize incoming calls for the respective contexts. If the property is marked for reentry, then callouts are intercepted too. The callout interception allows other waiting threads to enter the synchronization domain for maximal throughput.</p>
<div>
<table border="0">
<tbody>
<tr>
<th><!--src=[../icons/alert_note.gif]--><img src="http://i.msdn.microsoft.com/8bf9h00k.alert_note%28en-us,VS.90%29.gif" alt="Note" /><strong>Note:</strong></th>
</tr>
<tr>
<td>There are two classes named SynchronizationAttribute : one in the <a id="ctl00_MTCS_main_ctl56_ctl00_ctl01" href="http://msdn.microsoft.com/en-us/library/system.runtime.remoting.contexts.aspx">System.Runtime.Remoting.Contexts</a> namespace, and the other in the <a id="ctl00_MTCS_main_ctl56_ctl00_ctl02" href="http://msdn.microsoft.com/en-us/library/system.enterpriseservices.aspx">System.EnterpriseServices</a> namespace. The <a id="ctl00_MTCS_main_ctl56_ctl00_ctl03" href="http://msdn.microsoft.com/en-us/library/system.enterpriseservices.synchronizationattribute.aspx">System.EnterpriseServices..::.SynchronizationAttribute</a> class supports only synchronous calls, and can be used only with serviced components. (For more information on serviced components, see <a id="ctl00_MTCS_main_ctl56_ctl00_ctl04" href="http://msdn.microsoft.com/en-us/library/7c05y13x.aspx">[&#60;topic://cpconservicedcomponentoverview&#62;]</a>.) The System.Runtime.Remoting.Contexts..::.SynchronizationAttribute supports both synchronous and asynchronous calls, and can be used only with context bound objects. (For more information on context bound objects, see the <a id="ctl00_MTCS_main_ctl56_ctl00_ctl06" href="http://msdn.microsoft.com/en-us/library/system.contextboundobject.aspx">ContextBoundObject</a> class.)</td>
</tr>
</tbody>
</table>
</div>
<table border="0">
<tbody>
<tr>
<th><!--src=[../icons/alert_note.gif]--></th>
</tr>
</tbody>
</table>
<h1>Recommendations for Class Libraries</h1>
<div id="sectionSection4">
<p>Consider the following guidelines when designing class libraries for <strong>multithreading</strong>:</p>
<ul>
<li>Avoid the need for synchronization, if possible. This is especially true for heavily used code. For example, an algorithm might be adjusted to tolerate a race condition rather than eliminate it. Unnecessary synchronization decreases performance and creates the possibility of deadlocks and race conditions.</li>
<li>Make <strong>static </strong>data (<strong>Shared</strong> in Visual Basic) thread safe by default.</li>
<li>Do not make instance data thread safe by default. Adding locks to create thread-safe code decreases <strong>performance, </strong>increases lock contention, and creates the possibility for deadlocks to occur. In common application models, only one thread at a time executes user code, which minimizes the need for thread safety. For this reason, the .NET Framework class libraries are not thread safe by default.</li>
<li>Avoid providing static methods that alter static state. In common server scenarios, static state is shared across requests, which means multiple threads can execute that code at the same time. This opens up the possibility of threading bugs. Consider using a <strong>design pattern that encapsulates data into instances that are not shared across requests</strong>. Furthermore, if static data are synchronized, calls between static methods that alter state can result in deadlocks or redundant synchronization, adversely affecting performance.</li>
</ul>
</div>
<h1>General Recommendations</h1>
<p>Consider the following guidelines when using multiple threads:</p>
<ul>
<li>Don&#8217;t use <a id="ctl00_MTCS_main_ctl09" href="http://msdn.microsoft.com/en-us/library/system.threading.thread.abort%28VS.80%29.aspx">Thread.Abort</a> to terminate other threads. Calling <strong>Abort</strong> on another thread is akin to throwing an exception on that thread, without knowing what point that thread has reached in its processing.</li>
<li>Don&#8217;t use <a id="ctl00_MTCS_main_ctl10" href="http://msdn.microsoft.com/en-us/library/system.threading.thread.suspend%28VS.80%29.aspx">Thread.Suspend</a> and <a id="ctl00_MTCS_main_ctl11" href="http://msdn.microsoft.com/en-us/library/system.threading.thread.resume%28VS.80%29.aspx">Thread.Resume</a> to synchronize the activities of multiple threads. Do use</li>
<li>
<ul>
<li><a id="ctl00_MTCS_main_ctl12" href="http://msdn.microsoft.com/en-us/library/system.threading.mutex%28VS.80%29.aspx">Mutex</a>,</li>
<li><a id="ctl00_MTCS_main_ctl13" href="http://msdn.microsoft.com/en-us/library/system.threading.manualresetevent%28VS.80%29.aspx">ManualResetEvent</a>,</li>
<li><a id="ctl00_MTCS_main_ctl14" href="http://msdn.microsoft.com/en-us/library/system.threading.autoresetevent%28VS.80%29.aspx">AutoResetEvent</a>,</li>
<li><a id="ctl00_MTCS_main_ctl15" href="http://msdn.microsoft.com/en-us/library/system.threading.monitor%28VS.80%29.aspx">Monitor</a>.</li>
</ul>
</li>
<li><strong>Don&#8217;t control the execution of worker threads from your main program (using events, for ex</strong>ample). Instead, design your program so that worker threads are responsible for waiting until work is available, executing it, and notifying other parts of your program when finished. If your worker threads do not block, consider using <strong><a href="http://msdn.microsoft.com/en-us/library/0ka9477y.aspx">thread pool</a> threads</strong>. <a id="ctl00_MTCS_main_ctl16" href="http://msdn.microsoft.com/en-us/library/system.threading.monitor.pulseall%28VS.80%29.aspx">Monitor.PulseAll</a> is useful in situations where worker threads block.</li>
<li><a href="http://msdn.microsoft.com/en-us/magazine/cc164139.aspx#S1">The Birth of the Thread Pool</a><br />
<a href="http://msdn.microsoft.com/en-us/magazine/cc164139.aspx#S2">Capability 1: Calling a Method Asynchronously</a><br />
<a href="http://msdn.microsoft.com/en-us/magazine/cc164139.aspx#S3">Capability 2: Calling a Method at Timed Intervals</a><br />
<a href="http://msdn.microsoft.com/en-us/magazine/cc164139.aspx#S4">Capability 3: Calling a Method When a Single Kernel Object Becomes Signaled</a></li>
<li>Don&#8217;t use types as lock objects. That is, <strong>avoid code such as <tt>lock(typeof(X))</tt> in C#</strong> or <tt>SyncLock(GetType(X))</tt> in Visual Basic, or the use of <a id="ctl00_MTCS_main_ctl17" href="http://msdn.microsoft.com/en-us/library/de0542zz%28VS.80%29.aspx">System.Threading.Monitor.Enter(System.Object)</a> with <a id="ctl00_MTCS_main_ctl18" href="http://msdn.microsoft.com/en-us/library/system.type%28VS.80%29.aspx">Type</a> objects. For a given type, there is only one instance of <strong>System.Type</strong> per application domain. If the type you take a lock on is public, code other than your own can take locks on it, leading to deadlocks. For additional issues, see <a id="ctl00_MTCS_main_ctl19" href="http://msdn.microsoft.com/en-us/library/ms228970%28VS.80%29.aspx">Reliability Best Practices</a>.</li>
<li>Use caution when locking on instances, for example <tt>lock(this)</tt> in C# or <tt>SyncLock(Me)</tt> in Visual Basic. If <strong>other code in your application, external to the type, takes a lock on the object, deadlocks</strong> could occur.</li>
<li>Do ensure that a thread that has entered a monitor always leaves that monitor, even if an <strong>exception </strong>occurs while the thread is in the monitor. The C# <a id="ctl00_MTCS_main_ctl20" href="http://msdn.microsoft.com/en-us/library/c5kehkcz%28VS.80%29.aspx">lock</a> statement and the Visual Basic <a id="ctl00_MTCS_main_ctl21" href="http://msdn.microsoft.com/en-us/library/3a86s51t%28VS.80%29.aspx">SyncLock</a> statement provide this behavior automatically, employing a <strong>finally</strong> block to ensure that <a id="ctl00_MTCS_main_ctl22" href="http://msdn.microsoft.com/en-us/library/system.threading.monitor.exit%28VS.80%29.aspx">Monitor.Exit</a> is called. If you cannot ensure that <strong>Exit</strong> will be called, consider changing your design to use <strong>Mutex</strong>. A mutex is automatically released when the thread that currently owns it terminates.</li>
<li>Do use multiple threads for tasks that require different resources, and     <strong>avoid assigning multiple threads to a single resource</strong>. For example, any task involving I/O benefits from having its own thread, because that thread will block during I/O operations and thus allow other threads to execute. <strong>User input is another resource that benefits from a dedicated thread</strong>. On a single-processor computer, a task that involves intensive computation coexists with user input and with tasks that involve I/O, but <strong>multiple computation-intensive tasks contend with each other</strong>.</li>
<li>Consider using methods of the <a id="ctl00_MTCS_main_ctl23" href="http://msdn.microsoft.com/en-us/library/system.threading.interlocked%28VS.80%29.aspx">Interlocked</a> class for simple state changes, instead of using the <strong>lock</strong> statement (<strong>SyncLock</strong> in Visual Basic). The <strong>lock</strong> statement is a good general-purpose tool, but the <strong>Interlocked</strong> class provides better performance for updates that must be atomic. Internally, it executes a single lock prefix if there is no contention. In code reviews, watch for code like that shown in the following examples. In the first example, a state variable is incremented:</li>
</ul>
<p><strong>Performance Considerations with Locks, Threads, Semaphores</strong></p>
<dl>
<dt>You can improve performance by using the <a id="ctl00_MTCS_main_ctl26" href="http://msdn.microsoft.com/en-us/library/system.threading.interlocked.increment%28VS.80%29.aspx">Increment</a> method instead of the <strong>lock</strong> statement, as follows: </dt>
<dt>
</dt>
<dt><span id="ctl00_MTCS_main_ctl28"></p>
<div id="ctl00_MTCS_main_ctl28_CSharp">
<div>
<div>C#</div>
</div>
<div style="background-color:#dddddd;" dir="ltr">
<pre style="white-space:pre-wrap;">System.Threading.Interlocked.Increment(myField);</pre>
</div>
</div>
<p></span></dt>
</dl>
<p>In the second example, a <strong>reference type variable is updated only if it is a null reference</strong> (<em><strong>Nothing </strong></em>in Visual Basic).</p>
<p><span id="ctl00_MTCS_main_ctl30"> </span>C#         <span id="ctl00_MTCS_main_ctl31"> </span></p>
<div id="ctl00_MTCS_main_ctl31_CSharp">
<div style="background-color:#dddddd;" dir="ltr">
<pre style="white-space:pre-wrap;"><span style="color:blue;">if</span> (x == <span style="color:blue;">null</span>)
{
    lock (lockObject)
    {
        <span style="color:blue;">if</span> (x == <span style="color:blue;">null</span>)
        {
            x = y;
        }
    }
}</pre>
</div>
</div>
<p>Performance can be improved by using the <a id="ctl00_MTCS_main_ctl32" href="http://msdn.microsoft.com/en-us/library/system.threading.interlocked.compareexchange%28VS.80%29.aspx">CompareExchange</a> method instead, as follows:</p>
<p><span id="ctl00_MTCS_main_ctl33"> </span>C#         <span id="ctl00_MTCS_main_ctl34"> </span></p>
<div id="ctl00_MTCS_main_ctl34_CSharp">
<div style="background-color:#dddddd;" dir="ltr">
<pre style="white-space:pre-wrap;">System.Threading.Interlocked.CompareExchange(ref x, y, <span style="color:blue;">null</span>);</pre>
</div>
</div>
<p>The methods of this class help protect against errors that can occur when the scheduler switches contexts while a thread is updating a variable that can be accessed by other threads, or when two threads are executing concurrently on separate processors. The members of this class do not throw exceptions.The <a id="ctl00_MTCS_main_ctl32_ctl00_ctl00" href="http://msdn.microsoft.com/en-us/library/system.threading.interlocked.increment%28VS.80%29.aspx">Increment</a> and <a id="ctl00_MTCS_main_ctl32_ctl00_ctl01" href="http://msdn.microsoft.com/en-us/library/system.threading.interlocked.decrement%28VS.80%29.aspx">Decrement</a> methods increment or decrement a variable and store the resulting value in a single operation. On most computers, incrementing a variable is not an atomic operation, requiring the following steps:</p>
<ol>
<li>Load a value from an instance variable into a register.</li>
<li>Increment or decrement the value.</li>
<li>Store the value in the instance variable.</li>
</ol>
<p>If you do not use <strong>Increment</strong> and <strong>Decrement</strong>, a thread can be preempted after executing the first two steps. Another thread can then execute all three steps. When the first thread resumes execution, it overwrites the value in the instance variable, and the effect of the increment or decrement performed by the second thread is lost.</p>
<p>The <a id="ctl00_MTCS_main_ctl32_ctl00_ctl02" href="http://msdn.microsoft.com/en-us/library/system.threading.interlocked.exchange%28VS.80%29.aspx">Exchange</a> method atomically exchanges the values of the specified variables. The <a id="ctl00_MTCS_main_ctl32_ctl00_ctl03" href="http://msdn.microsoft.com/en-us/library/system.threading.interlocked.compareexchange%28VS.80%29.aspx">CompareExchange</a> method combines two operations: comparing two values and storing a third value in one of the variables, based on the outcome of the comparison. The compare and exchange operations are performed as an atomic operation.</p>
<p><span id="ctl00_MTCS_main_ctl33_ctl00_ctl01"> </span></p>
<pre style="white-space:pre-wrap;"><span style="color:green;">//A simple method that denies reentrancy.</span>
        <span style="color:blue;">static</span> <span style="color:blue;">bool</span> UseResource()
        {
            <span style="color:green;">//0 indicates that the method is not in use.</span>
            <span style="color:blue;">if</span>(0 == Interlocked.Exchange(ref usingResource, 1))
            {
                Console.WriteLine(<span style="color:maroon;"><span style="color:maroon;">"{0} acquired the lock"</span></span>, Thread.CurrentThread.Name);

                <span style="color:green;">//Code to access a resource that is not thread safe would go here.</span>

                <span style="color:green;">//Simulate some work</span>
                Thread.Sleep(500);

                Console.WriteLine(<span style="color:maroon;"><span style="color:maroon;">"{0} exiting lock"</span></span>, Thread.CurrentThread.Name);

                <span style="color:green;">//Release the lock</span>
                Interlocked.Exchange(ref usingResource, 0);
                <span style="color:blue;">return</span> <span style="color:blue;">true</span>;
            }
            <span style="color:blue;">else</span>
            {
                Console.WriteLine(<span style="color:maroon;"><span style="color:maroon;">"   {0} was denied the lock"</span></span>, Thread.CurrentThread.Name);
                <span style="color:blue;">return</span> <span style="color:blue;">false</span>;
            }
        }
</pre>
<h2>Source Code Examples</h2>
<dl>
<dt>
<ul>
<li><a title="Part-1 - Creating a thread in Windows Forms" href="http://bigballofmud.wordpress.com/2009/04/01/2009/03/21/thread-marshalling-part-1-creating-a-thread-in-windows-forms/">Part 1 – Creating a thread in Windows Forms</a> -  Some basic ideas about firing a background and how to synchronize it with the UI.</li>
<li><a title="Part 2 - using BackgroundWorker" href="http://bigballofmud.wordpress.com/2009/04/01/2009/03/28/thread-marshalling-part-2-using-backgroundworker/" target="_self">Part 2 – Using BackgroundWorker</a> -  the .NET 2.0 way using a BackgroundWorker component<a title="Part 2 - using BackgroundWorker" href="http://bigballofmud.wordpress.com/2009/04/01/2009/03/28/thread-marshalling-part-2-using-backgroundworker/"></a></li>
</ul>
<ul>
<li><a title="Part 3 - Automatic Marshalling" href="http://bigballofmud.wordpress.com/2009/03/21/2009/04/01/thread-marshalling-part-3-automatic-marshalling/" target="_self">Part 3 – Automatic Marshalling</a> – creating your own component with auto marshalling</li>
</ul>
</dt>
<h2>When Not to Use Thread Pool Threads</h2>
<div style="display:block;"><a id="sectionToggle0"></a>There are several scenarios in which it is appropriate to create and manage your own threads instead of using thread pool threads:</p>
<ul>
<li>You require a foreground thread.</li>
<li>You require a thread to have a particular priority.</li>
<li>You have tasks that cause the thread to block for long periods of time. The thread pool has a maximum number of threads, so a large number of blocked thread pool threads might prevent tasks from starting.</li>
<li>You need to place threads into a single-threaded apartment. All <a id="ctl00_MTCS_main_ctl64_ctl00_ctl00" href="http://msdn.microsoft.com/en-us/library/system.threading.threadpool.aspx">ThreadPool</a> threads are in the multithreaded apartment.</li>
<li>You need to have a stable identity associated with the thread, or to dedicate a thread to a task.</li>
</ul>
</div>
<dt><strong><a id="ctl00_MTCS_main_ctl01" href="http://msdn.microsoft.com/en-us/library/8xs8549b%28VS.80%29.aspx">BackgroundWorker Component Overview</a></strong></dt>
<dd>Describes the <strong>BackgroundWorker</strong> component, which gives you the ability to execute time-consuming operations asynchronously (&#8220;in the background&#8221;), on a thread different from your application&#8217;s main UI thread.
</dd>
</dl>
</div>
<p>There are many commonly performed operations that can take a long time to execute. For example:</p>
<ul>
<li>Image downloads</li>
<li>Web service invocations</li>
<li>File downloads and uploads (including for peer-to-peer applications)</li>
<li>Complex local computations</li>
<li>Database transactions</li>
<li>Local disk access, given its slow speed relative to memory access</li>
</ul>
<p><a id="ctl00_MTCS_main_ctl45_ctl00_ctl01" href="http://msdn.microsoft.com/en-us/library/system.marshalbyrefobject%28VS.80%29.aspx">System.MarshalByRefObject</a><br />
<a id="ctl00_MTCS_main_ctl45_ctl00_ctl02" href="http://msdn.microsoft.com/en-us/library/system.componentmodel.component%28VS.80%29.aspx">System.ComponentModel.Component</a><br />
<strong>System.ComponentModel.BackgroundWorker</strong></p>
<dl>
<dt><strong><a id="ctl00_MTCS_main_ctl14" href="http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker%28VS.80%29.aspx">BackgroundWorker</a> </strong></dt>
<dd>Describes this class and has links to all its members. </dd>
</dl>
<p>To execute a time-consuming operation in the background, create a <strong>BackgroundWorker</strong> and listen for events that report the progress of your operation and signal when your operation is finished. You can create the <strong>BackgroundWorker</strong> programmatically or you can drag it onto your form from the <strong>Components</strong> tab of the <strong>Toolbox</strong>. If you create the <strong>BackgroundWorker</strong> in the Windows Forms Designer, it will appear in the Component Tray, and its properties will be displayed in the Properties window.</p>
<p>To set up for a background operation, add an event handler for the <a id="ctl00_MTCS_main_ctl43_ctl00_ctl00" href="http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.dowork%28VS.80%29.aspx">DoWork</a> event. Call your time-consuming operation in this event handler. To start the operation, call <a id="ctl00_MTCS_main_ctl43_ctl00_ctl01" href="http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.runworkerasync%28VS.80%29.aspx">RunWorkerAsync</a>. To receive notifications of progress updates, handle the <a id="ctl00_MTCS_main_ctl43_ctl00_ctl02" href="http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.progresschanged%28VS.80%29.aspx">ProgressChanged</a> event. To receive a notification when the operation is completed, handle the <a id="ctl00_MTCS_main_ctl43_ctl00_ctl03" href="http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.runworkercompleted%28VS.80%29.aspx">RunWorkerCompleted</a> event.</p>
<div>
<table border="0" width="100%">
<tbody>
<tr>
<th align="left"><img src="http://i.msdn.microsoft.com/4852et58.note%28en-US,VS.80%29.gif" alt="Note" />Note:</th>
</tr>
<tr>
<td>You must be careful not to manipulate any user-interface objects in your <strong>DoWork</strong> event handler. Instead, communicate to the user interface through the <strong>ProgressChanged</strong> and <strong>RunWorkerCompleted</strong> events.<strong>BackgroundWorker</strong> events are not marshaled across <a id="ctl00_MTCS_main_ctl43_ctl00_ctl04" href="http://msdn.microsoft.com/en-us/library/system.appdomain%28VS.80%29.aspx">AppDomain</a> boundaries. Do not use a <strong>BackgroundWorker</strong> component to perform multithreaded operations in more than one <strong>AppDomain</strong>.</td>
</tr>
</tbody>
</table>
</div>
<p>If your background operation requires a parameter, call <strong>RunWorkerAsync</strong> with your parameter. Inside the <strong>DoWork</strong> event handler, you can extract the parameter from the <a id="ctl00_MTCS_main_ctl43_ctl00_ctl05" href="http://msdn.microsoft.com/en-us/library/system.componentmodel.doworkeventargs.argument%28VS.80%29.aspx">DoWorkEventArgs.Argument</a> property.</p>
<div>System.Threading..::.<span style="text-decoration:underline;"><strong>ThreadPool</strong></span></div>
<div>Remarks</div>
<div style="display:block;"><a id="remarksToggle"></a></p>
<div>
<table border="0">
<tbody>
<tr>
<th><!--src=[../icons/alert_note.gif]--><img src="http://i.msdn.microsoft.com/y5htx827.alert_note%28en-us,VS.90%29.gif" alt="Note" /><strong>Note:</strong></th>
</tr>
<tr>
<td>The <a id="ctl00_MTCS_main_ctl51_ctl00_ctl01" href="http://msdn.microsoft.com/en-us/library/system.security.permissions.hostprotectionattribute.aspx">HostProtectionAttribute</a> attribute applied to this type or member has the following <a id="ctl00_MTCS_main_ctl51_ctl00_ctl02" href="http://msdn.microsoft.com/en-us/library/system.security.permissions.hostprotectionattribute.resources.aspx">Resources</a> property value: <strong>Synchronization &#124; ExternalThreading</strong>. The <a id="ctl00_MTCS_main_ctl51_ctl00_ctl03" href="http://msdn.microsoft.com/en-us/library/system.security.permissions.hostprotectionattribute.aspx">HostProtectionAttribute</a> does not affect desktop applications (which are typically started by double-clicking an icon, typing a command, or entering a URL in a browser). For more information, see the <a id="ctl00_MTCS_main_ctl51_ctl00_ctl04" href="http://msdn.microsoft.com/en-us/library/system.security.permissions.hostprotectionattribute.aspx">HostProtectionAttribute</a> class or <a id="ctl00_MTCS_main_ctl51_ctl00_ctl05" href="http://msdn.microsoft.com/en-us/library/ms172338.aspx">SQL Server Programming and Host Protection Attributes</a>.</td>
</tr>
</tbody>
</table>
</div>
<p>Many applications create threads that spend a great deal of time in the sleeping state, waiting for an event to occur. Other threads might enter a sleeping state only to be awakened periodically to poll for a change or update status information. Thread pooling enables you to use threads more efficiently by providing your application with a pool of worker threads that are managed by the system. One thread monitors the status of several wait operations queued to the thread pool. When a wait operation completes, a worker thread from the thread pool executes the corresponding callback function.</p>
<div>
<table border="0">
<tbody>
<tr>
<th><!--src=[../icons/alert_note.gif]--><img src="http://i.msdn.microsoft.com/y5htx827.alert_note%28en-us,VS.90%29.gif" alt="Note" /><strong>Note:</strong></th>
</tr>
<tr>
<td>The threads in <a href="http://msdn.microsoft.com/en-us/library/0ka9477y.aspx"><strong>the managed thread pool</strong></a> are background threads. That is, their <a id="ctl00_MTCS_main_ctl51_ctl00_ctl07" href="http://msdn.microsoft.com/en-us/library/system.threading.thread.isbackground.aspx">IsBackground</a> properties are true. This means that a ThreadPool thread will not keep an application running after all foreground threads have exited.</td>
</tr>
</tbody>
</table>
</div>
<p>You can also queue work items that are not related to a wait operation to the thread pool. To request that a work item be handled by a thread in the thread pool, call the <a id="ctl00_MTCS_main_ctl51_ctl00_ctl08" href="http://msdn.microsoft.com/en-us/library/system.threading.threadpool.queueuserworkitem.aspx">QueueUserWorkItem</a> method. This method takes as a parameter a reference to the method or delegate that will be called by the thread selected from the thread pool. There is no way to cancel a work item after it has been queued.</p>
<p>Timer-queue timers and registered wait operations also use the thread pool. Their callback functions are queued to the thread pool.</p>
<blockquote><p>There is <strong>one thread pool per process</strong>. The thread pool has a default size of <strong>250 worker threads</strong> per available processor, and 1000 I/O completion threads. The number of threads in the thread pool can be changed by using the <a id="ctl00_MTCS_main_ctl51_ctl00_ctl09" href="http://msdn.microsoft.com/en-us/library/system.threading.threadpool.setmaxthreads.aspx">SetMaxThreads</a> method. Each thread uses the default stack size and runs at the default priority.</p></blockquote>
<p>The thread pool maintains a minimum number of idle threads. For worker threads, the default value of this minimum is the number of processors. The <a id="ctl00_MTCS_main_ctl51_ctl00_ctl11" href="http://msdn.microsoft.com/en-us/library/system.threading.threadpool.getminthreads.aspx">GetMinThreads</a> method obtains the minimum numbers of idle worker and I/O completion threads.</p>
<p>When all thread pool threads have been assigned to tasks, the thread pool does not immediately begin creating new idle threads. To avoid unnecessarily allocating stack space for threads, it creates new idle threads at intervals. The <strong>interval is currently half a second</strong>, although it could change in future versions of the .NET Framework.</p>
<p>If an application is subject to bursts of activity in which large numbers of thread pool tasks are queued, use the <a id="ctl00_MTCS_main_ctl51_ctl00_ctl12" href="http://msdn.microsoft.com/en-us/library/system.threading.threadpool.setminthreads.aspx">SetMinThreads</a> method to increase the minimum number of idle threads. Otherwise, the built-in delay in creating new idle threads could cause a bottleneck.</p>
<table border="0">
<tbody>
<tr>
<th><!--src=[../icons/alert_note.gif]--><img src="http://i.msdn.microsoft.com/y5htx827.alert_note%28en-us,VS.90%29.gif" alt="Note" /><strong>Note:</strong></th>
</tr>
<tr>
<td>Unnecessarily increasing the number of idle threads can also cause performance problems. Stack space must be allocated for each thread. If too many tasks start at the same time, all of them might appear to be slow. Finding the right balance is a <strong>performance-tuning issue</strong>.</td>
</tr>
</tbody>
</table>
<p>When the thread pool reuses a thread, it does not clear the data in thread local storage or in fields that are marked with the <a id="ctl00_MTCS_main_ctl51_ctl00_ctl14" href="http://msdn.microsoft.com/en-us/library/system.threadstaticattribute.aspx">ThreadStaticAttribute</a> attribute. Therefore, data that is placed in thread local storage by one method can be exposed to any other method that is executed by the same thread pool thread. A method that accesses a field that is marked with the <a id="ctl00_MTCS_main_ctl51_ctl00_ctl15" href="http://msdn.microsoft.com/en-us/library/system.threadstaticattribute.aspx">ThreadStaticAttribute</a> attribute could encounter different data depending on which thread pool thread executes it.</p>
<p>Starting with the .NET Framework version 2.0 Service Pack 1, the throughput of the thread pool is significantly improved for applications that make heavy use of small thread pool tasks. These applications will see improvements in three areas:</p>
<ul>
<li>queuing tasks,</li>
<li>dispatching thread pool threads, and</li>
<li>dispatching I/O completion threads.</li>
</ul>
<p>To use this functionality, your application should target the .NET Framework version 3.5. For more information, see <a id="ctl00_MTCS_main_ctl51_ctl00_ctl16" href="http://msdn.microsoft.com/en-us/library/bb822049.aspx">.NET Framework 3.5 Architecture</a>.</p>
<h2>More Samples, .NET Snippets</h2>
<p>use the <a href="http://msdn2.microsoft.com/en-us/library/system.componentmodel.isynchronizeinvoke.invoke.aspx" target="_blank">Invoke Method</a> of the <a href="http://msdn2.microsoft.com/en-us/library/system.componentmodel.isynchronizeinvoke.aspx" target="_blank">ISynchronizeInvoke</a> Interface:</p>
<p><!--c1--></p>
<div>CODE</div>
<div>
#region UpdateStatus<br />
private static void UpdateStatus(string msg, string status)<br />
{<br />
//create our Object Array<br />
object[] items = new object[2];<br />
//populate our array with the parameters<br />
//passed to our method<br />
items[0] = msg;<br />
items[1] = status;<br />
//call the delegate<br />
_synch.Invoke(_status, items);<br />
}<br />
#endregion</div>
<p><!--ec2--></p>
<p>Using this we can update any UI component in the main thread without worrying if the call is being made from the proper thread. So as you can see, there is a thread-safe way to share data between threads. Though we aren&#8217;t using data, we&#8217;re simply updating a component on the UI with the status of our background thread. This process can now rune while leaving the UI in a usable state.</p></div>
<p><strong><a href="http://msdn.microsoft.com/en-us/magazine/cc188792.aspx">Basic Instincts: Implementing Callbacks with a Multicast Delegate</a>.</strong></p>
<p>is a follow-up to the <a href="http://msdn.microsoft.com/msdnmag/issues/02/12/basicinstincts/default.aspx">December 2002</a> installment in which I introduced the basic concepts and programming techniques associated with delegates. I am going to assume you have already read that column and that you are familiar with the fundamentals of programming delegates. For example, you should know how to define a delegate type, how to create a delegate object that&#8217;s bound to a handler method, and how to execute the handler method by calling the delegate object&#8217;s Invoke method.</p>
<p><a href="http://msdn.microsoft.com/en-us/library/ms173175(VS.80).aspx">How to: Combine Delegates (Multicast Delegates)(C#)</a>.</p>
<p>This example demonstrates how to compose multicast delegates. A useful property of <a id="ctl00_MTCS_main_ctl02" href="http://msdn.microsoft.com/en-us/library/900fyy8e%28VS.80%29.aspx">delegate</a> objects is that they can be assigned to one delegate instance to be multicast using the <strong>+</strong> operator. A composed delegate calls the two delegates it was composed from. Only delegates of the same type can be composed.</p>
<p>The <strong>-</strong> operator can be used to remove a component delegate from a composed delegate.</p>
<h1>Example</h1>
<div id="codeExampleSection"><span id="ctl00_MTCS_main_ctl03"></p>
<div id="ctl00_MTCS_main_ctl03_CSharp">
<div>
<div>C#</div>
</div>
<div style="background-color:#dddddd;" dir="ltr">
<pre style="white-space:pre-wrap;">delegate <span style="color:blue;">void</span> Del(<span style="color:blue;">string</span> s);

<span style="color:blue;">class</span> TestClass
{
    <span style="color:blue;">static</span> <span style="color:blue;">void</span> Hello(<span style="color:blue;">string</span> s)
    {
        System.Console.WriteLine(<span style="color:maroon;"><span style="color:maroon;">"  Hello, {0}!"</span></span>, s);
    }

    <span style="color:blue;">static</span> <span style="color:blue;">void</span> Goodbye(<span style="color:blue;">string</span> s)
    {
        System.Console.WriteLine(<span style="color:maroon;"><span style="color:maroon;">"  Goodbye, {0}!"</span></span>, s);
    }

    <span style="color:blue;">static</span> <span style="color:blue;">void</span> Main()
    {
        Del a, b, c, d;

        <span style="color:green;">// Create the delegate object a that references </span>
        <span style="color:green;">// the method Hello:</span>
        a = Hello;

        <span style="color:green;">// Create the delegate object b that references </span>
        <span style="color:green;">// the method Goodbye:</span>
        b = Goodbye;

        <span style="color:green;">// The two delegates, a and b, are composed to form c: </span>
        c = a + b;

        <span style="color:green;">// Remove a from the composed delegate, leaving d, </span>
        <span style="color:green;">// which calls only the method Goodbye:</span>
        d = c - a;

        System.Console.WriteLine(<span style="color:maroon;"><span style="color:maroon;">"Invoking delegate a:"</span></span>);
        a(<span style="color:maroon;"><span style="color:maroon;">"A"</span></span>);
        System.Console.WriteLine(<span style="color:maroon;"><span style="color:maroon;">"Invoking delegate b:"</span></span>);
        b(<span style="color:maroon;"><span style="color:maroon;">"B"</span></span>);
        System.Console.WriteLine(<span style="color:maroon;"><span style="color:maroon;">"Invoking delegate c:"</span></span>);
        c(<span style="color:maroon;"><span style="color:maroon;">"C"</span></span>);
        System.Console.WriteLine(<span style="color:maroon;"><span style="color:maroon;">"Invoking delegate d:"</span></span>);
        d(<span style="color:maroon;"><span style="color:maroon;">"D"</span></span>);
    }
}</pre>
</div>
</div>
<p></span></p>
<h4>Output</h4>
<pre>Invoking delegate a:
  Hello, A!
Invoking delegate b:
  Goodbye, B!
Invoking delegate c:
  Hello, C!
  Goodbye, C!
Invoking delegate d:
  Goodbye, D!</pre>
</div>
<h1><span id="seeAlsoNoToggle">See Also</span></h1>
<h4>Reference</h4>
<p><a id="ctl00_MTCS_main_ctl04" href="http://msdn.microsoft.com/en-us/library/system.multicastdelegate%28VS.80%29.aspx">MulticastDelegate</a></p>
<h4>Concepts</h4>
<p><a id="ctl00_MTCS_main_ctl05" href="http://msdn.microsoft.com/en-us/library/67ef8sbd%28VS.80%29.aspx">C# Programming Guide</a><br />
<a id="ctl00_MTCS_main_ctl06" href="http://msdn.microsoft.com/en-us/library/awbftdfh%28VS.80%29.aspx">Events (C# Programming Guide)</a></p>
<h2><a href="http://msdn.microsoft.com/en-us/magazine/cc188792.aspx"><span id="ctl00_WikiContent_ctl00_HeaderTitle">Quick factories using delegates</span></a></h2>
<p>Delegates are very useful to act as object factories. In the example below, it is used to allow the function to build another object based on it, while keeping the function unaware about types.</p>
<pre>namespace Microsoft.MSDN.Wiki.Samples
{
    class Vehicle
    {
        int Price;
    }
    class Car : Vehicle
    {
        protected Car(string model, int passengers)
        {
        }
        public static Car Create(string model, int passengers)
        {
            // Perform some check and create a new instance
            return new Car(model, passengers);
        }
        public Vehicle FakeClone(Vehicle src)
        {
            // Cars are special in our example, and will not be cloned
            // return the original object instead
            return src;
        }
    }
    class Bus : Vehicle
    {
        private string model;
        private int passengers;
        private int cargo;
        protected Bus(string model, int passengers, int cargo)
        {
            // Assign variables
            this.model = model;
            this.passengers = passengers;
            this.cargo = cargo;
        }
        public static Bus Create(string model, int passengers, int cargo)
        {
            // TODO: Perform some check and create a new instance
            return new Bus(model, passengers, cargo);
        }
        public Vehicle CloneSpecial(Vehicle src)
        {
            // TODO: Perform some check and clone the instance
            Bus bus = (Bus)src;
            return new Bus(bus.model, bus.passengers, bus.cargo);
        }
    }
    class Program
    {
        <strong>public delegate Vehicle CreateNewVehicle(Vehicle src);</strong>
        public void ProcessBus(Bus bus)
        {
            ProcessVehicle(bus, <strong>bus.CloneSpecial</strong>);
        }
        public void ProcessCar(Car car)
        {
            ProcessVehicle(car, <strong>car.FakeClone</strong>);
        }
        public void ProcessVehicle(Vehicle source, <strong>CreateNewVehicle factory</strong>)
        {
            // This function might need to clone the vehicle. Use the delegate
            // so the caller can control the creation
            bool needToCloneObject = true;
            if (needToCloneObject)
            {
                Vehicle newObj = factory(source);
                if (newObj != null)
                {
                    // Now we have a new object to work with
                }
            }
        }
        [STAThread]
        public static void Main(string[] args)
        {
        }
    }
}
</pre>
<p>As you can see we can take the knowledge about the creation logic outside the function when pure inheritance does not work (e.g. having a generic Clone() function in Vehicle) or when the logic changing depending on the context. For example, you might need to clone in a specific way on one condition and clone it differently on another condition.</p>
<p><a href="http://msdn.microsoft.com/en-us/library/awbftdfh(VS.80).aspx"><br />
</a></p>
<h2><span id="ctl00_WikiContent_ctl01_HeaderTitle">Anonymous delegates can be used to simplify context changes</span></h2>
<p>you can also use an anonymous delegate to simplify the cloning process. But remember that this technique is not constrained to cloning. That was just the motivation for the example.</p>
<pre>namespace Microsoft.MSDN.Wiki.Samples
{
    class Vehicle
    {
        int Price;
    }
    class Car : Vehicle
    {
        protected Car(string model, int passengers)
        {
        }
        public static Car Create(string model, int passengers)
        {
            // Perform some check and create a new instance
            return new Car(model, passengers);
        }
    }
    class Bus : Vehicle
    {
        private string model;
        private int passengers;
        private int cargo;
        protected Bus(string model, int passengers, int cargo)
        {
            // Assign variables
            this.model = model;
            this.passengers = passengers;
            this.cargo = cargo;
        }
        public static Bus Create(string model, int passengers, int cargo)
        {
            // TODO: Perform some check and create a new instance
            return new Bus(model, passengers, cargo);
        }
        public Bus Clone()
        {
            return new Bus(this.model, this.passengers, this.cargo);
        }
    }
    class Program
    {
        public delegate Vehicle CreateNewVehicle(Vehicle src);
        public void ProcessBus(Bus bus)
        {
            ProcessVehicle(bus, <strong>delegate(Vehicle src)
            {
                // Perform some special logic
                return ((Bus)src).Clone();
            }</strong>);
        }
        public void ProcessCar(Car car)
        {
            ProcessVehicle(car, <strong>delegate(Vehicle src)
            {
                // Cars are not cloned in this situation
                return src;
            }</strong>);
        }
        public void ProcessVehicle(Vehicle source, CreateNewVehicle factory)
        {
            // This function might need to clone the vehicle. Use the delegate
            // so the caller can control the creation
            bool needToCloneObject = true;
            if (needToCloneObject)
            {
                Vehicle newObj = factory(source);
                if (newObj != null)
                {
                    // Now we have a new object to work with
                }
            }
        }
        [STAThread]
        public static void Main(string[] args)
        {
        }
    }
}</pre>
</div>
</div>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[What is the SQL Server 2008 DateTime2 Internal Structure?]]></title>
<link>http://sqlfascination.com/2009/10/11/what-is-the-sql-server-2008-datetime2-internal-structure/</link>
<pubDate>Sun, 11 Oct 2009 22:15:47 +0000</pubDate>
<dc:creator>andrewhogg</dc:creator>
<guid>http://sqlfascination.com/2009/10/11/what-is-the-sql-server-2008-datetime2-internal-structure/</guid>
<description><![CDATA[SQL Server has a number of new date time formats, but the one I am most interested in is DateTime2. ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>SQL Server has a number of new date time formats, but the one I am most interested in is DateTime2. The internal format of the SQL DateTime is commonly mistaken as 2&#215;4 byte integers, with the latter integer being milliseconds since midnight. It is in fact the number of 1/300ths of a second since midnight, which is why the accuracy of the DateTime within SQL Server has historically been 3.33ms. (If you really want to see it, crack it open by converting it to a binary, adding 1 and re-converting, you add 3.33ms, not 1 ms.)</p>
<p>So DateTime2 must use a different format, and as a weekend exercise that had no purpose than understanding the internals I thought I&#8217;d take a look. I have not seen the information in the BoL or posted as yet, so might be of use.  I am starting with the DateTime2(7) and looking at the maximum accuracy structure. The code used to crack it open each time is basically as follows:</p>
<pre><span style="color:#0000ff;">declare</span> @dt <span style="color:#0000ff;">datetime2</span>(7)
<span style="color:#0000ff;">set</span> @dt = <span style="color:#ff0000;">'2000/01/01 00:00:00'
</span><span style="color:#0000ff;">declare</span> @bin <span style="color:#0000ff;">varbinary</span>(<span style="color:#ff00ff;">max</span>)
<span style="color:#0000ff;">set</span> @bin = <span style="color:#ff00ff;">CONVERT</span>(<span style="color:#0000ff;">varbinary</span>(<span style="color:#ff00ff;">max</span>), @dt)</pre>
<p>To make my life easier, SQL conveniently outputs all the values as hexidecimal numbers. The results are not what you would expect.</p>
<pre>0x07000000000007240B
0x07000000000008240B</pre>
<p>The date which traditionally occupied the first 4 bytes, clearly is occupying the last few bytes. So the format is not going to be obvious or simple. interestingly the returned result is 9 bytes, but the length is quoted as 8. It is returning 8 when checked using the length, that first byte is somewhat odd to make an appearance.  It&#8217;s also suspiciously the accuracy value, and with a few tests using a change of accuracy, it show that value changes. So the first pseudo-byte is the accuracy indicator.</p>
<p>To start figuring out some more, let&#8217;s take the time back to the beginning point, which in this case is not 1900/01/01 but 0001/01/01 which when converted gives us:</p>
<pre>'0001/01/01 00:00:00' =&#62; 0x070000000000000000</pre>
<p>Start incrementing the day portion and there is an obvious pattern, the 6th byte changes.</p>
<pre>'0001/01/02 00:00:00' =&#62; 0x070000000000010000
'0001/01/03 00:00:00' =&#62; 0x070000000000020000
'0001/01/31 00:00:00' =&#62; 0x0700000000001E0000</pre>
<p>As you try the 2nd month, to check where the month is, the same byte alters, so it represents days, not specific date parts. Is it the number of days since the beginning of the year? No.</p>
<pre>'0001/02/01 00:00:00' =&#62; 0x0700000000001F0000</pre>
<p>If it was, there would be an issue since 1 byte does not represent enough values, as we can see, FF occurs on the 13th of September, and then it rolls over and puts a 1 in the 7th Byte position.</p>
<pre>'0001/09/13 00:00:00' =&#62; 0x070000000000FF0000
'0001/09/14 00:00:00' =&#62; 0x070000000000000100
'0001/09/15 00:00:00' =&#62; 0x070000000000010100</pre>
<p>It rolls over, then carries on as before. This immediately suggests the next test, to roll over the year, and the pattern continues.</p>
<pre> '0001/12/31 00:00:00' =&#62; 0x0700000000006C0100  
'0001/12/31 00:00:00' =&#62; 0x0700000000006D0100</pre>
<p>So the format is just counting, we see it in the example as hex, but it is a straight number count going on but the hex values are left-to-right. Only 2 bytes are used so far, which do not represent enough day combinations, add the third byte in by going past 180 years:</p>
<pre>'0180/06/06 00:00:00' =&#62; 0x070000000000FFFF00  
'0180/06/07 00:00:00' =&#62; 0x070000000000000001</pre>
<p>So the final byte is then increased, so the number of combinations becomes 16777215 &#8211; that seems a lot better and certainly going to cover the range required.</p>
<pre>'2001/01/01 00:00:00' =&#62; 0x07000000000075250B</pre>
<p>So that is the final 3 bytes decoded, a simple pattern - and provides the template of how the time is also stored.</p>
<pre>'0001/01/01 00:00:00.0000000' =&#62; 0x070000000000000000
'0001/01/01 00:00:00.0000001' =&#62; 0x070100000000000000
'0001/01/01 00:00:00.0000255' =&#62; 0x07FF00000000000000
'0001/01/01 00:00:00.0065535' =&#62; 0x07FFFF000000000000
'0001/01/01 00:00:00.0065536' =&#62; 0x070000010000000000</pre>
<p>So to check whether the format is the same,</p>
<pre>'0001/01/01 00:00:00.9999999' =&#62; 0x077F96980000000000</pre>
<p>Decode that again and it all matches:</p>
<pre><span style="color:#0000ff;">select </span>(152 * 256 * 256) + (150 * 256) + 127
-----------
9999999</pre>
<p>When we click over into 1 second exactly, we increment the first byte by 1, so the time portion is still represented in 100ns intervals, with the normal system of each byte counting up 1 every time the previous byte rolls over. As we get to the limit of the 3 bytes, it rolls into the 4th and then the 5th.</p>
<pre>'0001/01/01 00:00:01.0000000' =&#62; 0x078096980000000000</pre>
<p>So the internal format of the DateTime2(7) is decoded, not difficult but it is an interesting choice &#8211; it is now a straight binary number, with the Least Significant Byte being on the Left, the Most Significant being on the right (for each section.) Within the byte however, to convert it you must still read it right-to-left.</p>
<p>The first 5 bytes are recording how many time units intervals have passed since midnight, and the last 3 bytes recording how many days have passed since 0001/01/01.</p>
<p>The time unit intervals are dictated by the accuracy of the number, 100ns for DateTime2(7), and 1 Micro second intervals for a DateTime2(6) etc.  The way in which you interpret it does not change, but the units you are multiplying the time portion by, alters based on the accuracy.</p>
<p>You could construct 2 dates that are identical at a binary level, but due to the field meta-data on accuracy, they do not represent the same date time.</p>
<pre> declare @dt1 dt1 datetime2(6)
set @dt1 = '0001/01/01 00:00:00.000001'
declare @dt2 datetime2(7)
set @dt2 = '0001/01/01 00:00:00.0000001'

0x060100000000000000
0x070100000000000000 </pre>
<p> And that is perhaps why on output they automatically have prefixed the binary value with the datetime accuracy, so that they are not entirely identical? I&#8217;m not sure but would be interested to find out.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[today is sunday #yay]]></title>
<link>http://pricelessjunk.wordpress.com/2009/10/11/1321/</link>
<pubDate>Sun, 11 Oct 2009 06:52:22 +0000</pubDate>
<dc:creator>Priya</dc:creator>
<guid>http://pricelessjunk.wordpress.com/2009/10/11/1321/</guid>
<description><![CDATA[Its Sunday noon &amp; I&#8217;m listening to 15-20 minute odd songs by DT, browsing #interestingness]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><ul>
<li>Its Sunday noon &#38; I&#8217;m listening to 15-20 minute odd songs by DT, browsing #interestingness on flickr, randomly tweeting, stumbling.</li>
<li>My 1st internals got over yesterday.</li>
<li>I like how all my pending works are done [well, most] &#38; I can sit and do Nothing for the rest of the day.</li>
<li>Yesterday was one of the most fun filled days of my life in college. We went out to celebrate at Chung Wah and Came back to college and stayed there till evening.</li>
<li>I like how college is soo much more than school. Its not about &#8220;getting up in the morning, going to college, attending classes and coming back home&#8221;.</li>
<li>I got my camera back [which my Dads colleague had borrowed for 2 weeks] yesterday! What timing.</li>
<li>DT = Adrenaline Rush!!</li>
<li>My last.fm subscription has still not expired!! It was suppose to have expired months back! #imaybelucky</li>
<li>I&#8217;ve realized making random bullets on blog is much easier than having to talk about one single topic =P</li>
</ul>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Describing tables you can't DESC]]></title>
<link>http://mwidlake.wordpress.com/2009/10/07/describing-tables-you-cant-desc/</link>
<pubDate>Wed, 07 Oct 2009 15:46:11 +0000</pubDate>
<dc:creator>mwidlake</dc:creator>
<guid>http://mwidlake.wordpress.com/2009/10/07/describing-tables-you-cant-desc/</guid>
<description><![CDATA[This is more an oddity than anything particularly useful. Sometimes you can&#8217;t use the sql*plus]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>This is more an oddity than anything particularly useful. Sometimes you can&#8217;t use the sql*plus DESCRIBE {DESC} command on tables- but you might have an alternative.</p>
<p>I&#8217;m doing a lot of work for a client on a 10.2.0.3 database.  I have SELECT ANY DICTIONARY but not SELECT ANY TABLE privilege. This is because there is sensitive data in the database and it is duly protected {and this is certainly not the first time I have worked for a client with full dictionary access but not data access, it&#8217;s becoming normal}. I&#8217;m granted access to specific things as needs arise.</p>
<p>I knew I had to look at a table called AD_FAKE_STATS_COLUMNS.</p>
<pre class="brush: sql;">select count(*) from mdw.AD_FAKE_STATS_COLUMNS
/
select count(*) from mdw.AD_FAKE_STATS_COLUMNS
                         *
ERROR at line 1:
ORA-00942: table or view does not exist</pre>
<p>Have I got the table name wrong?</p>
<pre class="brush: sql;">select table_name,owner
from dba_tables
where table_name = 'AD_FAKE_STATS_COLUMNS'

TABLE_NAME                     OWNER
------------------------------ -----------------
AD_FAKE_STATS_COLUMNS          MDW</pre>
<p>OK, it is there, I don&#8217;t have access to it. Fine, I don&#8217;t want access to the data, I just want to see the structure of the table:</p>
<pre class="brush: sql;">desc mdw.AD_FAKE_STATS_COLUMNS
ERROR:
ORA-04043: object mdw.AD_FAKE_STATS_COLUMNS does not exist</pre>
<p>Oh. DESC in sql*plus does not work.</p>
<p>I can&#8217;t DESC a table I do not have access to carry out DML on. I&#8217;m going to have to go and ask someone to give me permission to see the table. How annoying. </p>
<p>Or do I?</p>
<pre class="brush: sql;">@tab_desc
Enter value for tab_name: AD_FAKE_STATS_COLUMNS
old 21: where table_name like upper (nvl('&#38;amp;TAB_NAME','W')&#124;&#124;'%')
new 21: where table_name like upper (nvl('AD_FAKE_STATS_COLUMNS','W')&#124;&#124;'%')

TAB_OWN  TAB_NAME              COL_NAME              M COL_DEF
-----------------------------------------------------------------
MDW      AD_FAKE_STATS_COLUMNS TABLE_NAME            Y VARCHAR2(30)
                               COLUMN_NAME           Y VARCHAR2(30)
                               COPY_STATS_FROM       N VARCHAR2(61)
                               LOW_VALUE_SQL         N VARCHAR2(100)
                               HIGH_VALUE_SQL        N VARCHAR2(100)
                               DISTINCT_SQL          N VARCHAR2(100)
                               DAYS_HIST_NULL_AVGLEN N NUMBER(3,0)</pre>
<p> <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>I have access to the data dictionary. So I can see the structure of the table, which after all is what I wanted and is what the client is happy for me to have.{I&#8217;ve never much liked the DESC command in sql*plus, I replaced it with a little sql script against the data dictionary years ago}.</p>
<p>In case you want it, here is the script:</p>
<pre class="brush: sql;">-- tab_desc.sql
-- Martin Widlake date? way back in the mists of time
-- my own replacement for desc.
-- 16/11/01 improved the data_type section
 SET PAUSE ON
 SET PAUSE 'Any Key...&#38;gt;'
 SET PAGES 24
col Tab_own form A10
col tab_name form a22 wrap
col col_name form a28 wrap
col col_def form A14
 break on tab_own skip 1 on tab_name skip 1
 spool tab_desc.lst
 select
 owner                               Tab_Own
,table_name             Tab_Name
,column_name            Col_Name
,decode(NULLABLE,'Y','N','Y') Mand
,data_type&#124;&#124;decode(data_type
       ,'NUMBER','('
        &#124;&#124;decode(to_char(data_precision)
                ,null,'38'
                ,     to_char(data_precision)&#124;&#124;
                      decode(data_scale,null,''
                                      ,      ','&#124;&#124;data_scale)
                 )
                    &#124;&#124;')'
       ,'DATE',null
       ,'LONG',null
       ,'LONG RAW',null
,'('&#124;&#124;Substr(DATA_LENGTH,1,5)&#124;&#124;')'
				     )  col_def
from dba_tab_columns
where table_name like upper (nvl('&#38;amp;TAB_NAME','WHOOPS')&#124;&#124;'%')
order by 1,2,column_id,3,4
/
spool off
clear col
--</pre>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Deputy Manager- International Sales &amp; Marketing]]></title>
<link>http://careeratkbs.wordpress.com/2009/09/30/deputy-manager-international-sales-marketing/</link>
<pubDate>Wed, 30 Sep 2009 05:34:02 +0000</pubDate>
<dc:creator>careeratkbs</dc:creator>
<guid>http://careeratkbs.wordpress.com/2009/09/30/deputy-manager-international-sales-marketing/</guid>
<description><![CDATA[Hi, Here the placement for Deputy Manager-International Sales &amp; Marketing. International Sales ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Hi,</p>
<p>Here the placement for <span style="color:#800080;"><strong>Deputy Manager-International Sales &#38; Marketing.</strong></span></p>
<h3><strong> </strong><strong><span style="color:#ff0099;font-size:medium;"><strong><a name="InternationalSales"></a></strong></span></strong></h3>
<p><strong>International Sales &#38; Marketing ( P Band Sales and Mktg)</strong><br />
<strong> </strong></p>
<p><span style="color:#008000;"><strong>KRA’s:</strong></span></p>
<ul>
<li>Throughput Contribution.</li>
<li>Capital Efficiency.</li>
<li>Operating Expense Control.</li>
</ul>
<p><span style="color:#008000;"><strong>Job Description:</strong></span></p>
<p>The vacancy is in the Sales &#38; Marketing department of PED.<br />
The incumbent will be responsible for:</p>
<li>Generating profitable orders.</li>
<li>Keep update of market intelligence relevant to the process industry.</li>
<li>Develop close working relationship with Domestic &#38; International customers.</li>
<li>Develop working relationship with inter functional departments viz.Design &#38; Estimation,PMC,Manufacturing.</li>
<li>Training &#38; Development of subordinates on a continous basis.</li>
<li>Make presentation to the clients.</li>
<p><span style="color:#008000;"><strong>Essential Qualification:</strong></span></p>
<ul>
<li> B.E / B.Tech/ Diploma in (Mech /Prod/ Chem / Metallurgy)</li>
</ul>
<p><span style="color:#008000;"><strong>Essential Experience :</strong></span></p>
<li>5 &#8211; 7 years in Fabrication industry with an exposure in Marketing.</li>
<p><span style="color:#008000;"><strong>Preferred Experience:</strong></span></p>
<ul>
<li> Critical Process Equipment.</li>
</ul>
<p><span style="color:#008000;"><strong>Special Skills Required:</strong></span></p>
<li>Product Knowledge (Namely Heat Exchanger,Reactor &#38; Vessels,Tower Internals &#38; Trays,etc.</li>
<li>Market Knowledge.</li>
<p><span style="color:#008000;"><strong>Request you to furnish following details in the CV:</strong></span><br />
1)       Year of passing and percentage in SSC.<br />
2)       Year of passing and percentage in HSC / Diploma<br />
3)       Year of passing and percentage in B.E.<br />
4)       Current Location.<br />
5)       Current and Expected CTC.<br />
6)       Contact Details (Mobile number, landline number and e-mail id)</p>
<p>Would you be interested ?</p>
<p>Please send us your latest updated profile with contact nos.current &#38;  expected salary details and joining time required to <a href="mailto:priya@kbsconsultants.com" target="_blank">priya@kbsconsultants.com</a></p>
<p>You may also suggest this opening to your friends who may be  interested.</p>
<p><strong><span style="color:#00cccc;">Further  Information:</span></strong></p>
<p><strong><span style="color:#3333ff;">KBS </span><span style="color:#ff0000;">Consultants<br />
</span></strong>Flat H,Kulothungan  Apts,<br />
No, 5 Natesan Road<br />
Ashoknagar,<br />
Chennai 600 083.India<br />
Phone:  +91-44 2489 5341 / 2371 9622</p>
<p><strong><span style="color:#00cccc;">Visit Our Sites:</span></strong></p>
<p><strong><span style="color:#663366;">International jobs:</span></strong> <a href="http://www.jobsearchworld.com/">http://www.jobsearchworld.com/</a></p>
<p><strong><span style="color:#663366;">SAP ERP Jobs :</span></strong> <a href="http://www.jobsvista.com/">http://www.jobsvista.com/</a></p>
<p><strong><span style="color:#663366;">Core Engineering Jobs :</span></strong> <a href="http://www.gotachance.com/">http://www.gotachance.com/</a></p>
<p><strong><span style="color:#663366;">Technology Jobs :</span></strong> <a href="http://www.kbsconsultants.com/">http://www.kbsconsultants.com/</a></p>
<p><strong><span style="color:#663366;">India Jobs :</span></strong> <a href="http://www.kbsconsultants.net.in/">http://www.kbsconsultants.net.in/</a></p>
<p><a href="http://www.kbsconsultants.org.in/">http://www.kbsconsultants.org.in/</a></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Data Dictionary Performance - reference]]></title>
<link>http://mwidlake.wordpress.com/2009/09/29/data-dictionary-performance-deep-detail/</link>
<pubDate>Tue, 29 Sep 2009 09:41:28 +0000</pubDate>
<dc:creator>mwidlake</dc:creator>
<guid>http://mwidlake.wordpress.com/2009/09/29/data-dictionary-performance-deep-detail/</guid>
<description><![CDATA[I&#8217;ve got a couple more postings on Data Dictionary performance to get where I plan to go to wi]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>I&#8217;ve got a couple more postings on Data Dictionary performance to get where I plan to go to with this, but if you want to deep-dive into far more technical details then go and check out <a href="http://dioncho.wordpress.com/2009/09/29/tuning-query-on-fixed-table/">Dion Cho&#8217;s excellent posting on fixed object indexes</a>.</p>
<p>I was not planning on getting into the sys.x$ fixed objects as you need SYS access to look at them, which not everyone has, but this is where Dion goes. His posts are always good, I need to check them far more.</p>
<p>As a soft-technical aside, I often mention to people when doing courses on SQL or writing standards or even the odd occasions I&#8217;ve discussed perception, that we Westerners are taught to read from left to right, top-to-bottom and we pick out left justification very well. Code laid out like the below we find easy to read:</p>
<pre class="brush: sql;">select pers.name1                surname
      ,pers.name2                first_forename
      ,pers.nameother            middle_names
      ,peap.appdate              appointment_date
      ,decode (addr.name_num_ind
                 ,'N', to_char(addr.housenum)
                 ,'V', addr.housename
                 ,'B', to_char(addr.housenum
                              &#124;&#124;' '&#124;&#124;addr.housename)
                                 house_no_name
      ,addr.address2             addr_street
      ,addr.address3             addr_town
      ,addr.address4             addr_dist
      ,addr.code                 addr_code
from person              pers
     ,address            addr
    ,person_appointments peap
where pers.addr_id     =addr.addr_uid
and   pers.pers_id     =peap.pers_id
and   pers.active_fl   ='Y'
and   pers.prim_cons   ='ANDREWSDP'
and   peap.latest_fl   ='Y'</pre>
<p>But this is not true of other cultures, where people do not read left to right, top to bottom. I have had this confirmed just a couple of times when people who were born in Eastern cultures are in the course/conversation.</p>
<p>So I was very interested to see Dion&#8217;s Korean version of the blogpost I reference above (I really hope <a href="http://ukja.tistory.com/257">this link here to the korean version</a> is stable).<br />
The main body of the page is on the right, not left, but the text appears to be left justified.</p>
<p>Of course, I am horribly ignorant, I do not know which direction Koreans read in <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_sad.gif' alt=':-(' class='wp-smiley' /> . I could be spouting utter rubbish.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Data Dictionary Performance #2]]></title>
<link>http://mwidlake.wordpress.com/2009/09/28/data-dictionary-performance-2/</link>
<pubDate>Mon, 28 Sep 2009 21:58:12 +0000</pubDate>
<dc:creator>mwidlake</dc:creator>
<guid>http://mwidlake.wordpress.com/2009/09/28/data-dictionary-performance-2/</guid>
<description><![CDATA[A couple of posts ago I demonstrated that the DBA_ views are general faster than the ALL_ views and ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>A couple of posts ago I demonstrated that the <a href="http://mwidlake.wordpress.com/2009/09/21/">DBA_ views are general faster than the ALL_ views and that adding an owner filter to DBA_ views is potentially quicker than selecting from the USER_ views</a>.</p>
<p>Something else I do automatically, to help performance, is always specify and link via the schema owner.</p>
<p>The below is based on a 10.2.0.3 database with fixed object statistics gathered, though a long while ago. A have a test partitioned table called TEST_P and I want to see how many blocks are in the table and also in the table partitions, so I link between DBA_TABLES and DBA_TAB_PARTITIONS. I only specify the table name as I know there is only one table called TEST_P:</p>
<pre class="brush: sql;">select dbta.table_name,dbta.blocks
       ,dtp.partition_name,dtp.blocks
from dba_tables         dbta
    ,dba_tab_partitions dtp
where dbta.table_name=dtp.table_name
and   dbta.table_name='TEST_P'

TABLE_NAME     BLOCKS PARTITION_     BLOCKS
---------- ---------- ---------- ----------
TEST_P           7394 ID_MAX            370
TEST_P           7394 ID_40K           1756
TEST_P           7394 ID_30K           1756
TEST_P           7394 ID_20K           1756
TEST_P           7394 ID_10K           1756
5 rows selected.
Elapsed: 00:00:00.04

Statistics
---------------------------------------------
          0  recursive calls
          0  db block gets
        782 consistent gets</pre>
<p>Now I do the same but specify the schema owner in the join.</p>
<pre class="brush: sql;">select dbta.table_name,dbta.blocks
      ,dtp.partition_name,dtp.blocks
from dba_tables         dbta
    ,dba_tab_partitions dtp
where dbta.table_name =dtp.table_name
AND   DBTA.OWNER      =DTP.TABLE_OWNER
and   dbta.table_name ='TEST_P'

TABLE_NAME     BLOCKS PARTITION_     BLOCKS
---------- ---------- ---------- ----------
TEST_P           7394 ID_MAX            370
TEST_P           7394 ID_40K           1756
TEST_P           7394 ID_30K           1756
TEST_P           7394 ID_20K           1756
TEST_P           7394 ID_10K           1756
5 rows selected.
Elapsed: 00:00:00.04

Statistics
--------------------------------------------
          0  recursive calls
          0  db block gets
        580 consistent gets</pre>
<p>Just for the record, I have run these statements several time so the consistent gets are constant. The form with the &#8220;AND DBTA.OWNER =DTP.TABLE_OWNER&#8221; line is consistently running at 580 consistent gets and the version without at 782 consistent gets.</p>
<p>If I now add in the where clause to look only for tables within the schema I am interested in, the code is even more efficient:</p>
<pre class="brush: sql;">select dbta.table_name,dbta.blocks
      ,dtp.partition_name,dtp.blocks
from dba_tables         dbta
    ,dba_tab_partitions dtp
where dbta.table_name =dtp.table_name
AND  DBTA.OWNER       =DTP.TABLE_OWNER
and   dbta.table_name ='TEST_P'
and   dbta.owner      =user

TABLE_NAME     BLOCKS PARTITION_     BLOCKS
---------- ---------- ---------- ----------
TEST_P           7394 ID_10K           1756
TEST_P           7394 ID_20K           1756
TEST_P           7394 ID_30K           1756
TEST_P           7394 ID_40K           1756
TEST_P           7394 ID_MAX            370
5 rows selected.
Elapsed: 00:00:00.03

Statistics
--------------------------------------------
          0  recursive calls
          0  db block gets
        137  consistent gets</pre>
<p>Down to 137 consistent gets.</p>
<p>It&#8217;s maybe not at all suprising that fully specifying the schema owner of the table we are interested in allows a more efficient path through the data dictionary, but it is something we all often fail to specify as it means writing more SQL, and it works quickly enough. For one table.<br />
But then if you convert a quick check script into part of your system housekeeping scripts and then use that housekeeping script on a very large database, things can start to run very slowly. I&#8217;ve never seen that happen, not with one of my own scripts, honest <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>The reason to always specify the schema owner, at all times when possible, when drilling down the data dictionary, is that so many things link back to sys.obj$ and it has an index with a leading column on owner {well,owner#}. The whole data dictionary tends towards 3rd normal form and parent-child relationships through IDs (name#, obj#, user#, ts#). <em>Schema</em> and name identify the objects and are one of the few links into this structure, which then links to other tables via obj# and other hash IDs.</p>
<pre class="brush: sql;">IND_NAME           TAB_NAME           PSN       COL_NAME
--------------- ------------------ --------- -------------
I_OBJ1          OBJ$               1         OBJ#

I_OBJ2          OBJ$               1         OWNER#
                                   2         NAME
                                   3         NAMESPACE
                                   4         REMOTEOWNER
                                   5         LINKNAME
                                   6         SUBNAME

I_OBJ3           OBJ$              1       OID$</pre>
<p>So my advice is, if you are looking at data dictionary views where the schema owner is involved, always include that column in the join and always filter by schema owner if you can. And if things are still slow, pull out the view code and look at the indexes on the underlying sys.$ views. After all, the data dictionary is, to all intents and purposes, just a normal normalised database.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Friday Philosophy - A Comment on Comments]]></title>
<link>http://mwidlake.wordpress.com/2009/09/25/friday-philosophy-a-comment-on-comments/</link>
<pubDate>Fri, 25 Sep 2009 13:18:01 +0000</pubDate>
<dc:creator>mwidlake</dc:creator>
<guid>http://mwidlake.wordpress.com/2009/09/25/friday-philosophy-a-comment-on-comments/</guid>
<description><![CDATA[This blog is not about blog comments. It&#8217;s about table and column comments in the data diction]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>This blog is not about blog comments. It&#8217;s about table and column comments in the data dictionary.</p>
<p>Some of you may well be going &#8220;huh?&#8221;. Others are probably going &#8220;Oh yes, I remember them?&#8221;. Table and column comments appear to be suffering the same fate as ERDs, who&#8217;s slow demise I bemoaned <a href="http://mwidlake.wordpress.com/2009/09/14/">a couple of weeks ago</a>. They are becoming a feature not known about or used by those with &#8220;less personal experience of history&#8221; {ie younger}.</p>
<p>It&#8217;s a simple principle, you can add a comment against a table or a column,up to 4000 characters. {you can also add comments against index types, materialized views and operators (huh?), at least in 10.2}.</p>
<pre class="brush: sql;">comment on table widlakem.person is
'Test table of fake people for training purposes, approx 50k records'
Comment created.

select * from dba_tab_comments
where owner='WIDLAKEM'
and table_name = 'PERSON'

OWNER      TABLE_NAME                     TABLE_TYPE
---------- ------------------------------ -----------
COMMENTS
--------------------------------------------------------------------------
WIDLAKEM PERSON TABLE
Test table of fake people for training purposes, approx 50k records

--

comment on column widlakem.person.second_forename is
'null allowed, second or middle name. If more than one, delimited by / character'

select * from dba_col_comments
where owner='WIDLAKEM' and table_name = 'PERSON'
and column_name='SECOND_FORENAME'

OWNER      TABLE_NAME                     COLUMN_NAME
---------- ------------------------------ ------------------------------
COMMENTS
-------------------------------------------------------------------------------
WIDLAKEM PERSON SECOND_FORENAME
null allowed, second or middle name. If more than one, delimited by / character
</pre>
<p>So you can stick basic information into the data dictionary where it will remain with the object until the object is dropped or the comment is updated. (You can&#8217;t drop a comment, you can only update it to &#8221;:</p>
<p>&#62;comment on table widlakem.person is &#8221;;</p>
<p>It&#8217;s simple, it&#8217;s sensible, it&#8217;s solid.</p>
<p>And it seems to be dying out. In fact, I had stopped adding comments to my tables and columns as no one else seemed to bother. Probably as a consequence of them not being added, no one ever seemed to think to look at them to get hints about the database structure and table/column use.</p>
<p>But Raj sitting next to me is as old a hand at this game as myself and I &#8220;caught&#8221; him adding comments to the little schema we are working on together. Well, if he is bothering, so will I!</p>
<p>How about Oracle Corp? How do they manage on this front? After all, the Oracle Reference manual has all these short descriptions of tables and columns in the data dictionary {some helpful, some utterly unhelpful}:</p>
<pre class="brush: sql;">select owner,count(*) from dba_tab_comments
where owner in ('SYS','SYSTEM','SYSMAN')
group by owner
OWNER        COUNT(*)
---------- ----------
SYSTEM            151
SYSMAN 472
SYS 3894

3 rows selected.</pre>
<p>Heyyyy, nice Oracle.</p>
<pre class="brush: sql;">select owner,table_name,comments
from dba_tab_comments
where owner in ('SYS','SYSTEM','SYSMAN')

OWNER      TABLE_NAME
---------- ------------------------------
COMMENTS
-----------------------------------------------------
SYS ICOL$

SYS CON$

SYS FILE$

SYS        UET$

SYS        IND$
SYSTEM     MVIEW_RECOMMENDATIONS
This view gives DBA access to summary recommendations
SYSTEM     MVIEW_EXCEPTIONS
This view gives DBA access to dimension validation results
SYSTEM     AQ$_QUEUE_TABLES
SYS        SEG$

SYS        COL$

SYS        CLU$
SYSTEM     SQLPLUS_PRODUCT_PROFILE

SYSTEM     PRODUCT_PRIVS

SYSTEM     HELP

SYSMAN MGMT_NOTIFY_QTABLE

SYSMAN AQ$MGMT_NOTIFY_QTABLE_S</pre>
<p>Oh. Lots of blanks. Not so nice Oracle. No, scrub that, several lines are not blank, so Not a bad attempt Oracle.</p>
<p>Why all the blanks? Why have Oracle set blank comments? That&#8217;s because a blank table comment gets created when you create a table, and a blank column comment is created per column.</p>
<pre class="brush: sql;">create table mdw_temp (col1 number);
Table created.

select * from dba_tab_comments where table_name = 'MDW_TEMP';
OWNER      TABLE_NAME                     TABLE_TYPE
---------- ------------------------------ -----------
COMMENTS
----------------------------------------------------------------------
WIDLAKEM   MDW_TEMP                       TABLE

1 row selected.

select * from dba_col_comments where table_name='MDW_TEMP';
OWNER      TABLE_NAME                     COLUMN_NAME
---------- ------------------------------ ---------------
COMMENTS
-------------------------------------------------------------------------
WIDLAKEM   MDW_TEMP                       COL1

1 row selected.</pre>
<p>So what populated system-like comments do we have?</p>
<p>select owner,count(*) from dba_tab_comments<br />
where owner in (&#8216;SYS&#8217;,'SYSTEM&#8217;,'SYSMAN&#8217;)<br />
and comments is not null<br />
group by owner</p>
<p>OWNER COUNT(*)<br />
&#8212;&#8212;&#8212;- &#8212;&#8212;&#8212;-<br />
SYSTEM 73<br />
SYSMAN 15<br />
SYS 944</p>
<p>OK, there are some, and as you can see below, some are more useful than others&#8230;</p>
<pre class="brush: sql;">OWNER      TABLE_NAME
---------- ---------------
COMMENTS
----------------------------------------------------------------------------------------------------
SYS        SYSTEM_PRIVILEG
           E_MAP
Description table for privilege type codes.  Maps privilege  type numbers to type names
SYS        TABLE_PRIVILEGE
           _MAP
Description table for privilege (auditing option) type codes.  Maps privilege (auditing option) type
numbers to type names
SYS        STMT_AUDIT_OPTI
           ON_MAP
Description table for auditing option type codes.  Maps auditing option type numbers to type names
SYS        RESOURCE_MAP
Description table for resources.  Maps resource name to number
SYS        SESSION_PRIVS
Privileges which the user currently has set
SYS        SESSION_ROLES
Roles which the user currently has enabled.
SYS        ROLE_SYS_PRIVS
System privileges granted to roles
SYS        ROLE_TAB_PRIVS
Table privileges granted to roles
SYS        ROLE_ROLE_PRIVS
Roles which are granted to roles
Oracle_DatabaseInstance contains one entry for each Oracle Instance that is
centrally managed.  A Real Application Cluster has one entry for each of the
instances that manipulate it.  Instances of Oracle_DatabaseInstance are created
using the database instances that are known to the Oracle Enterprise Manager
repository.
SYS        DBA_AUDIT_OBJECT
Audit trail records for statements concerning objects, specifically: table, cluster, view, index, se
uence, [public] database link, [public] synonym, procedure, trigger, rollback segment, tablespace, r
ole, user
SYS        USER_AUDIT_OBJECT
Audit trail records for statements concerning objects, specifically: table, cluster, view, index, se
uence, [public] database link, [public] synonym, procedure, trigger, rollback segment, tablespace, r
ole, user
SYSMAN     ORACLE_DATABASESTATISTICS
Oracle_DatabaseStatistics provides current information about the statistics for
a database.  Database statistics pertain to the database and have the same
value regardless of the database instance that is used.
SYSMAN     ORACLE_DBINSTANCESTATISTICS
Oracle_DBInstanceStatistics contains statistics for a database instance.  These
are retrieved from the Oracle Managment Repository that is managing the
database upon request from a managment client.</pre>
<p>If you don&#8217;t add comments to tables and comments, you will just have blank entries for them in the data dictionary.</p>
<p>So why not pop a few real comments in there, especially for any tables or comments where the name is not really telling you what that column or table is for? It&#8217;s free and easy, and it might just prove useful. And if you add them to your tables, I&#8217;ll add them to mine.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Beware Deleted Tables]]></title>
<link>http://mwidlake.wordpress.com/2009/09/22/beware-deleted-tables/</link>
<pubDate>Tue, 22 Sep 2009 15:04:43 +0000</pubDate>
<dc:creator>mwidlake</dc:creator>
<guid>http://mwidlake.wordpress.com/2009/09/22/beware-deleted-tables/</guid>
<description><![CDATA[From version 10 onwards, Oracle introduced the concept of the recycle bin and the purge command. I w]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>From version 10 onwards, Oracle introduced the concept of the recycle bin and the purge command. I won&#8217;t go into details of the recycle bin, go to <a href="http://www.orafaq.com/node/968">Natalka Roshak&#8217;s FAQ page on it</a> if you want the details.</p>
<p>I am only concerned with the fact that from Oracle 10 onwards <strong>by default if you drop a table or partition it is not dropped but just <em>renamed,</em></strong> unless you use the PURGE command {which can be tricky if you are using a 9i client as PURGE won&#8217;t be accepted by SQL*Plus}.</p>
<p>And it keeps catching me out. So I&#8217;m blogging about it &#8211;  more for me than any of you lot <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> ).</p>
<p>How exactly does it catch me out? Well, as an example,  I&#8217;m looking at some partitioning considerations at the moment and ran the below.</p>
<pre class="brush: sql;">select count(distinct(table_name)) from dba_tables
where partitioned='YES'
and owner='ERIC'

COUNT(DISTINCT(TABLE_NAME))
---------------------------
393
Elapsed: 00:00:00.14

Statistics
----------------------------------------------------------
8 recursive calls
0 db block gets
7079 consistent gets

select count(distinct(table_name))
from dba_part_tables
where owner='ERIC'

COUNT(DISTINCT(TABLE_NAME))
---------------------------
419
Elapsed: 00:00:00.07

Statistics
--------------------------------------------
8 recursive calls
0 db block gets
14084 consistent gets</pre>
<p>419 records from DBA_PART TABLES and 393 from DBA_TABLES.</p>
<p>How can that be? How can you have more records with partition information than tables with PARTITIONED flag set to YES?</p>
<p>{And for readers of my post yesterday on <a href="http://mwidlake.wordpress.com/2009/09/21/data-dictionary-performance/">querying the data dictionary</a>, check which of the statements performs better &#8211; one might expect the view specific to partitions to be quicker than one that is not, but then the partition-specific view is looking at a lot more under the covers}.</p>
<p>OK, Let&#8217;s find the objects in DBA_PART_TABLES not in DBA_TABLES</p>
<pre class="brush: sql;">SELECT DISTINCT TABLE_NAME FROM DBA_PART_TABLES
WHERE OWNER ='ERIC'
minus
SELECT DISTINCT TABLE_NAME FROM DBA_TABLEs
WHERE PARTITIONED='YES'
AND OWNER='ERIC'

TABLE_NAME
------------------------------
BIN$c0wxEyj93/vgQKAKQstN+w==$0
BIN$c59mEBlzOvLgQKAKQssjNA==$0
BIN$c6D0zY7yTrvgQKAKQssmdQ==$0
BIN$c6FJQBU6FG3gQKAKQssxCw==$0
BIN$c9qFcYojb/LgQKAKQssyVQ==$0
BIN$c9qFcYokb/LgQKAKQssyVQ==$0
BIN$c9qFcYolb/LgQKAKQssyVQ==$0
BIN$c9qFcYoqb/LgQKAKQssyVQ==$0
BIN$c9t8m70OdEXgQKAKQss4LA==$0
BIN$c9tu0S7KoUngQKAKQss39w==$0
BIN$c9uGpjGSbcvgQKAKQss4fw==$0
BIN$cWfis1j/BGPgQKAKQss7Lw==$0
BIN$cWft6d2mNcvgQKAKQss7qQ==$0
(snip)
BIN$czz0jembWe/gQKAKQsthhg==$0
BIN$czzu+/hC+yTgQKAKQsthpw==$0

26 rows selected.</pre>
<p>All 26 records are for deleted objects. You can tell they are deleted as the name is &#8220;<strong>BIN$</strong>something&#8221;.</p>
<p>That&#8217;s the thing that keeps catching me out, I keep forgetting to exclude deleted but not purged objects from maintenence scripts. *sigh*.</p>
<p>DBA_TABLES has a DROPPED column but other views do not, so you have to exclude on the name, which is not ideal. Someone might want to create a table called &#8220;BIN$somthing&#8221;.</p>
<p>Mind you, the DROPPED column is not much help:<br />
select count(*) from dba_tables WHERE DROPPED !=&#8217;NO&#8217;</p>
<p>COUNT(*)<br />
&#8212;&#8212;&#8212;-<br />
0</p>
<p>So that is as much use a chocolate teapot.<br />
{some little bell is ringing in my head that you need special privs to see the dropped tables. I have DBA role and I can&#8217;t&#8230;}</p>
<p>This does highlight something very, <strong><em>very</em></strong> odd though.</p>
<p>Why have the records gone from DBA_TABLES and not DBA_PART_TABLES?</p>
<p>Because the concept of the wastebasket has not been around long enough with V10.2 of Oracle for it to work consistently <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>I&#8217;ll check DBA_OBJECTS for the last object name in the above list:</p>
<pre class="brush: sql;">select * from dba_objects
where object_name='BIN$cxIzaly77FzgQKAKQst5tg==$0'

OWNER OBJECT_NAME SUBOBJECT_NAME OBJECT_ID
--------------------------------------------------------
DATA_OBJECT_ID OBJECT_TYPE CREATED LAST_DDL_TIME
--------------------------------------------------------
TIMESTAMP STATUS T G S
---------------------------
ERIC BIN$cxIzaly77FzgQKAK 2613938
Qst5tg==$0
TABLE 08-SEP-2009 13:49 08-SEP-2009 14:10
2009-09-08:14:10:02 VALID N N N</pre>
<p>And I can still look at it {note the use of quotes to allow for an object name with mixed case}:</p>
<p>DESC ERIC.&#8221;BIN$cxIzaly77FzgQKAKQst5tg==$0&#8243;<br />
Name Null? Type<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211; &#8212;&#8212;&#8211; &#8212;&#8212;&#8212;&#8212;<br />
LOAD_LOG_ID NUMBER(12)<br />
LOG_DATE DATE<br />
ABCDEFG_ID NUMBER(12)<br />
REMOTE_ADDRESS VARCHAR2(20)<br />
KGBHFDERS NUMBER(12)<br />
PRODUCT_ID NUMBER(12)<br />
KNGFDRET NUMBER(22)<br />
WKNHGFYTRERDS NUMBER(12)<br />
CHANNEL_TYPE VARCHAR2(1)<br />
COUNT_HITS NUMBER(12)<br />
MFDKEMNFK NUMBER(12)<br />
COUNT_NON_WEIGHTED NUMBER(12)</p>
<p>I can still select from it with the right privileges as well {I&#8217;ve not shown this, I&#8217;m out of time}.</p>
<p>In conclusion:</p>
<ul>
<li>Objects that are dropped but not purged are still in the data dictionary.</li>
<li>You may have to exclude such objects using the fact that the name starts &#8216;BIN$&#8230;&#8217;.</li>
<li>Dropped objects appear in some parts of the data dictionary but not others.</li>
<li>You can still and in fact look at dropped objects.</li>
<li>I have a poor memory.</li>
</ul>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Data Dictionary Performance]]></title>
<link>http://mwidlake.wordpress.com/2009/09/21/data-dictionary-performance/</link>
<pubDate>Mon, 21 Sep 2009 17:43:47 +0000</pubDate>
<dc:creator>mwidlake</dc:creator>
<guid>http://mwidlake.wordpress.com/2009/09/21/data-dictionary-performance/</guid>
<description><![CDATA[Which data dictionary view you use to look at information about your schemas and objects can be impo]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Which data dictionary view you use to look at information about your schemas and objects can be important from a performance point of view.</p>
<p>{Part two <a href="http://mwidlake.wordpress.com/2009/09/28/data-dictionary-performance-2/">is here.</a>}</p>
<p>Try this:</p>
<p>set autotrace on statistics<br />
set timi on<br />
set pause off</p>
<p>select count(tablespace_name) from user_tables;<br />
select count(tablespace_name) from all_tables;<br />
select count(tablespace_name) from dba_tables;</p>
<p>You might want to execute each select statement a couple of times until the <strong>consistent gets</strong> are stable.</p>
<p>These are the stats off my test system, version 10.2.0.3:</p>
<p>USER_TABLES<br />
8 records<br />
0.14 seconds<br />
14217 consistent gets</p>
<p>ALL_TABLES<br />
4455 records<br />
0.34 seconds<br />
29097 consistent gets</p>
<p>DBA_TABLES<br />
4455 records<br />
0.21 seconds<br />
16834 consistent gets</p>
<p>The select against user_tables is fastest and uses the least consistent gets as the view implicitly limits the search to your objects with the clause &#8220;where o.owner# = userenv(&#8216;SCHEMAID&#8217;)&#8221;. You use the USER_ views when you really only want to see your objects.</p>
<p>More interesting are the timings for ALL_TABLES and DBA_TABLES. I have SELECT_ANY_TABLE and SELECT_ANY_DICTIONARY so I see all tables with either view. But the DBA_ view is quicker and takes less consistent gets than the ALL_ view.</p>
<p>The reason is that the ALL_ views take into account checking your privileges to see if you have the right to see any particular object. The DBA_ views do not as you can only see them if you have system privileges to do so.</p>
<p>ALL_TABLES includes the following to check for access rights:</p>
<pre class="brush: sql;">and (o.owner# = userenv('SCHEMAID')
or o.obj# in
(select oa.obj#
from sys.objauth$ oa
where grantee# in ( select kzsrorol
from x$kzsro
)
)
or /* user has system privileges */
exists (select null from v$enabledprivs
where priv_number in (-45 /* LOCK ANY TABLE */,
-47 /* SELECT ANY TABLE */,
-48 /* INSERT ANY TABLE */,
-49 /* UPDATE ANY TABLE */,
-50 /* DELETE ANY TABLE */)
)
)</pre>
<p>So, if you are using an account that has access rights to see everything (DBA access typically), use the DBA_ views and they will perform better.</p>
<p>If you only want your objects then the best performance will come from using the USER_ views and not the ALL_ views, correct? It makes sense! Remember my cautions in earlier posts about theory and practice. There is a sting in this particular tale&#8230;</p>
<p>select count(tablespace_name) from user_tables;<br />
COUNT(TABLESPACE_NAME)<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
8<br />
Elapsed: 00:00:00.15</p>
<p>Statistics<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
0 recursive calls<br />
0 db block gets<br />
14217 consistent gets</p>
<p>Compared to</p>
<p>select count(tablespace_name) from all_tables<br />
where owner=USER;<br />
COUNT(TABLESPACE_NAME)<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
8<br />
Elapsed: 00:00:00.10</p>
<p>Statistics<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
0 recursive calls<br />
0 db block gets<br />
4117 consistent gets</p>
<p><strong>selecting from ALL_TABLES and filtering by USER performs significantly better on my system than using the USER_TABLES view!</strong></p>
<p>One caveat. I suspect my test system has poor fixed-object statistics, so I would be interested if anyone else finds different results on their system.</p>
</div>]]></content:encoded>
</item>

</channel>
</rss>
