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

<channel>
	<title>C# Help &#187; Threading</title>
	<atom:link href="http://www.csharphelp.com/tag/threading/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.csharphelp.com</link>
	<description>C# Tutorial and Guides</description>
	<lastBuildDate>Tue, 07 Feb 2012 01:03:28 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Use  ReaderWriterLockSlim to Protect Access to Resources in C#</title>
		<link>http://www.csharphelp.com/2010/07/use-readerwriterlockslim-to-protect-access-to-resources-in-c/</link>
		<comments>http://www.csharphelp.com/2010/07/use-readerwriterlockslim-to-protect-access-to-resources-in-c/#comments</comments>
		<pubDate>Thu, 22 Jul 2010 17:04:36 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[C# Language]]></category>
		<category><![CDATA[ReaderWriterLockSlim]]></category>
		<category><![CDATA[Threading]]></category>

		<guid isPermaLink="false">http://www.csharphelp.com/?p=2370</guid>
		<description><![CDATA[It is normally safe to allow let multiple threads read data at the same time, but when a thread is required to perform a write, all other threads will need to be blocked. The .NET framework originally provided ReaderWriterLock for this circumstance, but it has performance issues which often outweigh its usefulness. No address this, [...]]]></description>
			<content:encoded><![CDATA[<p>It is normally safe to allow let multiple threads read  data at the same time, but when a thread is required to perform a write, all other threads will need to be blocked. The .NET framework originally provided  <code>ReaderWriterLock </code> for this circumstance, but it has performance issues which often outweigh its usefulness. No address this,  <code>ReaderWriterLockSlim</code> has been introduced which corrects many of the issues with <code>ReaderWriterLock </code>.</p>
<p>The below code demonstrates using a <code>ReaderWriterLockSlim </code> on an array which is shared between a single writer and three readers:</p>
<pre>
class ReaderWriterLockDemo
{
const int MaxNumberValues = 30;
static int[] _array = new int[MaxNumberValues];
static ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();
static void Main(string[] args)
{
ThreadPool.QueueUserWorkItem(WriteThread);
for (int i = 0; i < 3; i++)
{
ThreadPool.QueueUserWorkItem(ReadThread);
}
Console.ReadKey();
}
static void WriteThread(object state)
{
int id = Thread.CurrentThread.ManagedThreadId;
for (int i = 0; i < MaxNumberValues; ++i)
{
_lock.EnterWriteLock();
Console.WriteLine(“Entered WriteLock on thread {0}”, id);
_array[i] = i*i;
Console.WriteLine(“Added {0} to array on thread {1}”, _
array[i], id);

Console.WriteLine(“Exiting WriteLock on the thread {0}”, id);
_lock.ExitWriteLock();
Thread.Sleep(1000);
}
}
static void ReadThread(object state)
{
int idNumber = Thread.CurrentThread.ManagedThreadId;
for (int i = 0; i < MaxNumberValues; ++i)
{
_lock.EnterReadLock();
Console.WriteLine(“Entered ReadLock on the thread {0}”, idNumber);
StringBuilder sbObj = new StringBuilder();
for (int j = 0; j < i; j++)
{
if (sbObj.Length > 0) sbObj.Append(“, “);
sbObj.Append(_array[j]);
}
Console.WriteLine(“Array: {0} on the thread {1}”, sbObj, idNumber);
Console.WriteLine(“Exiting the ReadLock on thread {0}”, idNumber);
_lock.ExitReadLock();
Thread.Sleep(10000);
}
}
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.csharphelp.com/2010/07/use-readerwriterlockslim-to-protect-access-to-resources-in-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Protect Data on Multiple Processes using C#</title>
		<link>http://www.csharphelp.com/2010/07/protect-data-multiple-processes-using-c/</link>
		<comments>http://www.csharphelp.com/2010/07/protect-data-multiple-processes-using-c/#comments</comments>
		<pubDate>Wed, 21 Jul 2010 16:48:11 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[C# Language]]></category>
		<category><![CDATA[Mutex]]></category>
		<category><![CDATA[Parallel]]></category>
		<category><![CDATA[Threading]]></category>

		<guid isPermaLink="false">http://www.csharphelp.com/?p=2367</guid>
		<description><![CDATA[If you have a routine which splits data across processors using the Parallel class you may need to protect memory, files or other resources which are shared across the multiple processes. One solution to this is to use a mutex, which is similar to a Monitor object, but at the operating system level. Mutexes must [...]]]></description>
			<content:encoded><![CDATA[<p>If you have a routine which <a href="http://www.csharphelp.com/2010/07/using-the-parallel-class-in-c/">splits data across processors using the Parallel class</a> you may need to protect memory, files or other resources which are shared across the multiple processes. One solution to this is to use a mutex, which is similar to a <code>Monitor </code>object, but at the operating system level. Mutexes must be named to ensure that both processes can open the exact same mutex object.</p>
<p>The below sample  uses a mutex to protect a file from being written to by two instances of this same program:</p>
<pre>
static void Main(string[] args)
{
Mutex mutexObj = new Mutex(false, “MutexDemo1”);
Process me = Process.GetCurrentProcess();
string outputFile = “MutexDemoOutput1.txt”;
while (!Console.KeyAvailable)
{
mutexObj.WaitOne();
Console.WriteLine(“The process {0} gained control”, me.Id);
using (FileStream fsObj = new FileStream(outputFile,
FileMode.OpenOrCreate))
using (TextWriter writer = new StreamWriter(fsObj))
{
fsObj.Seek(0, SeekOrigin.End);
string outputObj = string.Format(“The process {0} writing timestamp
 {1}”, me.Id, DateTime.Now.ToLongTimeString());
writer.WriteLine(outputObj);
Console.WriteLine(outputObj);
}
Console.WriteLine(“The process {0} releasing control”, me.Id);
mutexObj.ReleaseMutex();
Thread.Sleep(1000); }
}
</pre>
<p>As with a <code>Monitor </code> object, you may attempt a wait on a mutex for a <code>TimeSpan</code> before giving up, and in case the mutex gives up <code>WaitOne</code> will return false.</p>
<p>In the above code, each process will lock the mutex before then writing to the file. Ensure you select good names for your mutexes, you should either use a unique combination of your application, company, and mutex purpose, or else use a  GUID  to make sure no collisions with your own applciations or others.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.csharphelp.com/2010/07/protect-data-multiple-processes-using-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using the Parallel Class in C# &#8211; Run Tasks in Parallel on Multiple Processors or Cores</title>
		<link>http://www.csharphelp.com/2010/07/using-the-parallel-class-in-c-run-tasks-in-parallel-on-multiple-processors-or-cores/</link>
		<comments>http://www.csharphelp.com/2010/07/using-the-parallel-class-in-c-run-tasks-in-parallel-on-multiple-processors-or-cores/#comments</comments>
		<pubDate>Mon, 19 Jul 2010 12:04:08 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[C# Language]]></category>
		<category><![CDATA[Parallel]]></category>
		<category><![CDATA[Relection]]></category>
		<category><![CDATA[Threading]]></category>

		<guid isPermaLink="false">http://www.csharphelp.com/?p=2362</guid>
		<description><![CDATA[The Parallel Class can be used to split up the tasks which work on the data. For example if you have iterative code that looks like the below code: //6 parts of the book string[] inputTextFiles = { “part1.txt”, “part2.txt”, “part3.txt”, “part4.txt”, “part5.txt”, “part6.txt” }; foreach (string file in inputTextFiles) { string contentStr = File.ReadAllText(file); CountCharacters(contentStr); [...]]]></description>
			<content:encoded><![CDATA[<p>The Parallel Class can be used to split up the tasks which work on the data. For example if you have iterative code that looks like the below code:</p>
<pre>//6 parts of the book
string[] inputTextFiles =
{
“part1.txt”, “part2.txt”, “part3.txt”,
“part4.txt”, “part5.txt”, “part6.txt”
};

foreach (string file in inputTextFiles)

{
string contentStr = File.ReadAllText(file);
CountCharacters(contentStr);
CountWords(contentStr);
}</pre>
<p>The Parallel class can be used with lambda expressions to parallelize the two calculation methods:</p>
<pre>foreach(string file in inputFiles)

{
string contentStr = File.ReadAllText(file);
Parallel.Invoke(
() =&gt; CountCharacters(contentStr),
() =&gt; CountWords(contentStr)
);
}</pre>
<p>The results from using the Parallel Class to split tasks are normally not as dramatic  as using <a href="http://www.csharphelp.com/2010/07/using-the-parallel-class-in-c/">Parallel to split data across processors</a> but they are still significant.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.csharphelp.com/2010/07/using-the-parallel-class-in-c-run-tasks-in-parallel-on-multiple-processors-or-cores/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using the Parallel Class in C# &#8211; Processing Data in Parallel across Multiple Processors or Cores</title>
		<link>http://www.csharphelp.com/2010/07/using-the-parallel-class-in-c/</link>
		<comments>http://www.csharphelp.com/2010/07/using-the-parallel-class-in-c/#comments</comments>
		<pubDate>Mon, 19 Jul 2010 11:46:24 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[C# Language]]></category>
		<category><![CDATA[Parallel]]></category>
		<category><![CDATA[Threading]]></category>

		<guid isPermaLink="false">http://www.csharphelp.com/?p=2357</guid>
		<description><![CDATA[The new Task Parallel Library introduced with .NET 4, allows you to easily split code execution onto multiple processors without using threads or locks. For a task which is easily split into independent sub-tasks, or data that can be partitioned and computed separately you can use the Parallel class in System.Threading to assign tasks to [...]]]></description>
			<content:encoded><![CDATA[<p>The new Task Parallel Library introduced with .NET 4, allows you to easily split  code execution onto multiple processors without using threads or locks.</p>
<p>For a task which is easily split into independent sub-tasks, or data that can be partitioned and computed separately you can use the Parallel class in  System.Threading  to assign tasks to be automatically scheduled and then wait for the tasks to be  completed. The Parallel class will automatically scale to the number of available processors or cores.</p>
<h3>Process Data in Parallel across Multiple Processors or Cores</h3>
<p>When you have a  data set which  can be split over multiple processors and then processed independently, you should use constructs such as Parallel.For(), in the below example this is demonstrated for  computing prime numbers:</p>
<pre>using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;

namespace  PrimesDemo
{
class Program
{
static void Main(string[] args)
{
int maxPrimes = 1000000;
int maxNumber = 200000000;
long primesFound = 0;
Console.WriteLine(“Iterative”);
Stopwatch watchObj = new Stopwatch();
watchObj.Start();

for (UInt32 i = 0; i &lt; maxNumber; ++i) { if (IsPrime(i)) { Interlocked.Increment(ref primesFound); if (primesFound &gt; maxPrimes)
{
Console.WriteLine(“Last prime found was: {0:N0}”,
i);
break;
}
}
}
watchObj.Stop();
Console.WriteLine(“Found {0:N0} prime numbers in {1}”,
primesFound, watchObj.Elapsed);
watchObj.Reset();
primesFound = 0;
Console.WriteLine(“Parallel”);
watchObj.Start();
// to stop the loop, there is an overload that takes Action
Parallel.For(0, maxNumber, (i, loopState) =&gt;
{
if (IsPrime((UInt32)i))
{
Interlocked.Increment(ref primesFound);
if (primesFound &gt; maxPrimes)
{
Console.WriteLine(“Last prime found was: {0:N0}”,
i);
loopState.Stop();
}
}
});
watchObj.Stop();
Console.WriteLine(“Found {0:N0} prime numbers in {1}”,
primesFound, watchObj.Elapsed);
Console.ReadKey();
}
public static bool IsPrime(UInt32 number)
{

//check for evenness
if (number % 2 == 0)
{
if (number == 2)
return true;
return false;
}

UInt32 max = (UInt32)Math.Sqrt(number);
for (UInt32 i = 3; i &lt;= max; i += 2)
{
if ((number % i) == 0)
{
return false;
}
}
return true;
}
}
}</pre>
<p>When you run this note the drastically reduced time using Parallel, also note  that the  results are not  necessarily in order and that the parallel evaluation of the data does not arrive at the same results as the iterative evaluation. As opposed to running sequentially from 1 to 200,000,000 until one million primes are found, the input space is instead divided up and therefore it is possible to get different results in some circumstances.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.csharphelp.com/2010/07/using-the-parallel-class-in-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Multi Threaded Calculations in C#</title>
		<link>http://www.csharphelp.com/2007/09/multi-threaded-calculations-in-c/</link>
		<comments>http://www.csharphelp.com/2007/09/multi-threaded-calculations-in-c/#comments</comments>
		<pubDate>Thu, 20 Sep 2007 04:01:01 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[C# Language]]></category>
		<category><![CDATA[Threading]]></category>

		<guid isPermaLink="false">http://www.csharphelp.com.php5-3.dfw1-2.websitetestlink.com/?p=672</guid>
		<description><![CDATA[Introduction This C# .NET test harness configures easilycomparing throughput results of multi-threaded and single threadedcalculations using ADO .NET datasets. This simple multi-threadedexample performs calculation and database updates three times fasterthan a single threaded approach. Creating the Workspace To start the test harness, open a MicrosoftVisual Studio 2005, .NET Framework Version 2.0 development environmentand create two [...]]]></description>
			<content:encoded><![CDATA[<p><span class="smallblack">Introduction</span></p>
<p><span class="smallblack">This C# .NET test harness configures easilycomparing throughput results of multi-threaded and single threadedcalculations using ADO .NET datasets. This simple multi-threadedexample performs calculation and database updates three times fasterthan a single threaded approach.</span></p>
<p><span class="smallblack">Creating the Workspace</span></p>
<p><span class="smallblack">To start the test harness, open a MicrosoftVisual Studio 2005, .NET Framework Version 2.0 development environmentand create two Console Applications. The first application performscalculations using a scheduler and worker threads. The secondapplication performs calculations in a single thread.</span></p>
<p><span class="smallblack">Code</span></p>
<p><span class="smallblack">Both applications create an ADO .NET datasetof inventory from a fictitious database table called INVENTORYcontaining fields for the ID, COST, PRICE and PROFIT. The sample codeincludes database SQL scripts containing the ID and COST for samplesizes up to 10000 data points. The test harness calculates the PRICEand PROFIT for each data point and updates the database.</span></p>
<p><span class="smallblack">The multi-threaded test harness starts a worker thread for each calculation and database update.</span></p>
<p><span class="smallestblack"><span class="smallblack">public class CalculatorScheduler<br />{<br /> private DataSet m_invDataSet;</p>
<p> public void Init()<br /> {<br /> try<br /> {<br /> m_invDataSet = (new InventoryData()).GetDataSet();<br /> foreach (DataRow row in m_invDataSet.Tables[Properties.Settings.Default.TABLE_DS].Rows)<br /> {<br /> Thread t = new Thread(new ParameterizedThreadStart(ProcessCalculations));<br /> t.Start(row);<br /> }<br /> }<br /> catch (Exception exc)<br /> {<br /> exc.Message.ToString();<br /> }<br /> }<br /> private void ProcessCalculations(object row)<br /> {<br /> new CalculatorWorker().Calc((DataRow) row);<br /> }<br />}</p>
<p>public class CalculatorWorker<br />{<br /> private static Decimal MARGIN = Convert.ToDecimal(1.1);<br /> private static object item = new object();</p>
<p> public void Calc(DataRow row)<br /> {<br /> try<br /> {<br /> row.BeginEdit();<br /> row[Properties.Settings.Default.PRICE] = Convert.ToDecimal(row[Properties.Settings.Default.COST]) * MARGIN;<br /> row[Properties.Settings.Default.PROFIT] = Convert.ToDecimal(row[Properties.Settings.Default.PRICE]) &#8211; Convert.ToDecimal(row[Properties.Settings.Default.COST]);<br /> row.EndEdit();<br /> row.AcceptChanges();<br /> UpdateInventory(row);<br /> }<br /> catch (Exception exc)<br /> {<br /> exc.Message.ToString();<br /> }<br /> }</p>
<p> private void UpdateInventory(DataRow row)<br /> {<br /> try<br /> {<br /> OdbcCommand m_UpdateRatingsCmd = new OdbcCommand(Properties.Settings.Default.UPDATE, DBWrapper.Instance.InitializeConnection());<br /> m_UpdateRatingsCmd.Parameters.AddWithValue(&quot;@PRICE&quot;, Convert.ToDouble(row[Properties.Settings.Default.PRICE]));<br /> m_UpdateRatingsCmd.Parameters.AddWithValue(&quot;@PROFIT&quot;, Convert.ToDouble(row[Properties.Settings.Default.PROFIT]));<br /> m_UpdateRatingsCmd.Parameters.AddWithValue(&quot;@ID&quot;, Convert.ToInt32(row[Properties.Settings.Default.ID]));<br /> m_UpdateRatingsCmd.ExecuteNonQuery();<br /> DBWrapper.Instance.CloseConnection();<br /> }<br /> catch (Exception exc)<br /> {<br /> exc.Message.ToString();<br /> }<br />}<br />}<br /></span>
<p><span class="smallblack">Whereas the single threaded test harness performs the calculations linearly. </span></p>
<p><span class="smallestblack"><span class="smallblack">m_invDataSet = (new InventoryData()).GetDataSet();<br />foreach (DataRow row in m_invDataSet.Tables[Properties.Settings.Default.TABLE_DS].Rows)<br />{<br /> try<br /> {<br /> row.BeginEdit();<br /> row[Properties.Settings.Default.PRICE] = Convert.ToDecimal(row[Properties.Settings.Default.COST]) * MARGIN;<br /> row[Properties.Settings.Default.PROFIT] = Convert.ToDecimal(row[Properties.Settings.Default.PRICE]) &#8211; Convert.ToDecimal(row[Properties.Settings.Default.COST]);<br /> row.EndEdit();<br /> row.AcceptChanges();</p>
<p> OdbcCommand m_UpdateRatingsCmd = new OdbcCommand(Properties.Settings.Default.UPDATE, DBWrapper.Instance.InitializeConnection());<br /> m_UpdateRatingsCmd.Parameters.AddWithValue(&quot;@PRICE&quot;, Convert.ToDouble(row[Properties.Settings.Default.PRICE]));<br /> m_UpdateRatingsCmd.Parameters.AddWithValue(&quot;@PROFIT&quot;, Convert.ToDouble(row[Properties.Settings.Default.PROFIT]));<br /> m_UpdateRatingsCmd.Parameters.AddWithValue(&quot;@ID&quot;, Convert.ToInt32(row[Properties.Settings.Default.ID]));<br /> m_UpdateRatingsCmd.ExecuteNonQuery();<br /> DBWrapper.Instance.CloseConnection();<br /> }<br />}</p>
<p></span>
<p><span class="smallblack">Tests of different sample sizes showsignificantly faster results from the multi-threaded solution comparedto the single threaded solution. All Start Time and End Time values arein seconds. In this simple example the multi-threaded test harnessachieves an average of 1000 calculation and database updates per secondfor a dataset of 5000 records more than three times the rate of thesingle threaded approach. The test harnesses could be modified toperform more complex calculations for larger datasets; however, thissimple example presents the benefits of multi-threaded calculations.</span></p>
<p><span class="smallblack">Multi-Threaded Test Harness for Data Set of 1000333 calculation and db updates per second</span></p>
<p><span class="smallestblack"><span class="smallblack">Start Time : 27 <br />End Time : 30 </p>
<p>Single Threaded Test Harness For Data Set of 1000<br />200 calculation and db updates per second</p>
<p>Start Time : 23<br />End Time : 32</p>
<p>Multi-Threaded Test Harness for Data Set of 5000<br />1000 calculation and db updates per second</p>
<p>Start Time : 10<br />End Time : 15</p>
<p>Single Threaded Test Harness for Data Set of 5000<br />333 calculation and db updates per second</p>
<p>Start Time : 19<br />End Time : 34</p>
<p></span>
<p><span class="smallblack">Download <a href="http://www.csharphelp.com/archives4/files/archive692/Projects.zip">Source &amp; SQL</a></span></p>
]]></content:encoded>
			<wfw:commentRss>http://www.csharphelp.com/2007/09/multi-threaded-calculations-in-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Multithreading Made Easier in C#</title>
		<link>http://www.csharphelp.com/2007/07/multithreading-made-easier-in-c/</link>
		<comments>http://www.csharphelp.com/2007/07/multithreading-made-easier-in-c/#comments</comments>
		<pubDate>Mon, 16 Jul 2007 04:01:01 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[C# Language]]></category>
		<category><![CDATA[Threading]]></category>

		<guid isPermaLink="false">http://www.csharphelp.com.php5-3.dfw1-2.websitetestlink.com/?p=606</guid>
		<description><![CDATA[* * * Multithreading Made Easier * Created by Anand. * Bihar,India * User: Administrator * Date: 4/3/2005 * Time: 2:36 PM * See how easier its to create multithreadedapplications * Like Java ( I have tried to imitate Java,sRunnable and Thread ) * You have to do just 4 things : * 1)Create a [...]]]></description>
			<content:encoded><![CDATA[<p><span class="smallestblack"><span><span class="smallblack">*<br /> *<br /> * Multithreading Made Easier<br /> * Created by Anand.<br /> * Bihar,India<br /> * User: Administrator<br /> * Date: 4/3/2005<br /> * Time: 2:36 PM<br /> * See how easier its to create multithreaded<br />applications<br /> * Like Java ( I have tried to imitate Java,s<br />Runnable and Thread )<br /> * You have to do just 4 things :<br /> * 1)Create a class which implements<br />AObject.Runnable<br /> * 2)Create an object of above class<br /> * 3)Create an object of AObject.Thread passing<br />it the reference of object in step 2<br /> * 4) Class start() method of AObject.Thread<br />object<br /> You must be thinking why I didnot try just extending System.<br /> Threading.Thread Because Its a sealed class !!! In near future I will<br /> be adding ThreadGroup Class to AObject Namespace and many more&#8230;<br /> Try these codes&#8230;<br /> mail me to and_and007in@yahoo.co.in<br /> or anandindnr@yahoo.co.in<br /> Enjoy !<br /> *<br /> * To change this template use Tools | Options |<br />Coding | Edit Standard Headers.<br /> */<br />using System;<br />using System.Drawing;<br />using System.Windows.Forms;</p>
<p>namespace MultiThreadedWin<br />{<br /> /// &lt;summary&gt;<br /> /// Description of MainForm.<br /> /// &lt;/summary&gt;<br /> public class MainForm : System.Windows.Forms.Form<br /> {<br /> private System.Windows.Forms.Button bResume2;<br /> private System.Windows.Forms.Button bClear1;<br /> private System.Windows.Forms.Button bResume1;<br /> private System.Windows.Forms.Button bSuspend1;<br /> private System.Windows.Forms.Button bSuspend2;<br /> private System.Windows.Forms.TextBox textBox1;<br /> private System.Windows.Forms.Button bThread1;<br /> private System.Windows.Forms.Button bStop1;<br /> private System.Windows.Forms.TextBox textBox2;<br /> private System.Windows.Forms.Button bThread2;<br /> private System.Windows.Forms.Button bStop2;<br /> private System.Windows.Forms.Button bClear2;<br /> private AObject.Thread tt1;<br /> private AObject.Thread tt2;<br /> public MainForm()<br /> {<br /> //<br /> // The InitializeComponent() call is required for<br />Windows Forms designer support.<br /> //</p>
<p> InitializeComponent();<br /> tt1=new AObject.Thread(new PrintHello(textBox1));<br /> tt2=new AObject.Thread(new PrintHello(textBox2));</p>
<p> //<br /> // TODO: Add constructor code after the<br />InitializeComponent() call.<br /> //<br /> }<br /> static void mess(String str)<br /> {<br /> System.Windows.Forms.MessageBox.Show (str);<br /> }</p>
<p> [STAThread]<br /> public static void Main(string[] args)<br /> {<br /> //mess(&quot;Hello&quot;);<br /> MainForm mf;<br /> Application.Run(mf=new MainForm());<br /> mf.dispose ();</p>
<p> //mess(&quot;Bye&quot;);<br /> }</p>
<p> #region Windows Forms Designer generated code<br /> /// &lt;summary&gt;<br /> /// This method is required for Windows Forms<br />designer support.<br /> /// Do not change the method contents inside the<br />source code editor. The Forms designer might<br /> /// not be able to load this method if it was<br />changed manually.<br /> /// &lt;/summary&gt;<br /> private void InitializeComponent() {<br /> this.bClear2 = new System.Windows.Forms.Button();<br /> this.bStop2 = new System.Windows.Forms.Button();<br /> this.bThread2 = new System.Windows.Forms.Button();<br /> this.textBox2 = new System.Windows.Forms.TextBox();<br /> this.bStop1 = new System.Windows.Forms.Button();<br /> this.bThread1 = new System.Windows.Forms.Button();<br /> this.textBox1 = new System.Windows.Forms.TextBox();<br /> this.bSuspend2 = new System.Windows.Forms.Button();<br /> this.bSuspend1 = new System.Windows.Forms.Button();<br /> this.bResume1 = new System.Windows.Forms.Button();<br /> this.bClear1 = new System.Windows.Forms.Button();<br /> this.bResume2 = new System.Windows.Forms.Button();<br /> this.SuspendLayout();<br /> //<br /> // bClear2<br /> //<br /> this.bClear2.Location = new<br />System.Drawing.Point(216, 208);<br /> this.bClear2.Name = &quot;bClear2&quot;;<br /> this.bClear2.Size = new System.Drawing.Size(168,<br />24);<br /> this.bClear2.TabIndex = 5;<br /> this.bClear2.Text = &quot;Clear&quot;;<br /> this.bClear2.Click += new System.EventHandler(this.BClear2Click);<br /> //<br /> // bStop2<br /> //<br /> this.bStop2.Location = new<br />System.Drawing.Point(216, 304);<br /> this.bStop2.Name = &quot;bStop2&quot;;<br /> this.bStop2.Size = new System.Drawing.Size(168,<br />24);<br /> this.bStop2.TabIndex = 7;<br /> this.bStop2.Text = &quot;Stop Thread2&quot;;<br /> this.bStop2.Click += new System.EventHandler(this.BStop2Click);<br /> //<br /> // bThread2<br /> //<br /> this.bThread2.Location = new<br />System.Drawing.Point(216, 240);<br /> this.bThread2.Name = &quot;bThread2&quot;;<br /> this.bThread2.Size = new System.Drawing.Size(168,<br />24);<br /> this.bThread2.TabIndex = 0;<br /> this.bThread2.Text = &quot;Start Thread2&quot;;<br /> this.bThread2.Click += new System.EventHandler(this.BThread2Click);<br /> //<br /> // textBox2<br /> //<br /> this.textBox2.Location = new<br />System.Drawing.Point(216, 16);<br /> this.textBox2.Multiline = true;<br /> this.textBox2.Name = &quot;textBox2&quot;;<br /> this.textBox2.ScrollBars = System.Windows.Forms.ScrollBars.Both;<br /> this.textBox2.Size = new System.Drawing.Size(168,<br />184);<br /> this.textBox2.TabIndex = 3;<br /> this.textBox2.Text = &quot;&quot;;<br /> //<br /> // bStop1<br /> //<br /> this.bStop1.Location = new System.Drawing.Point(16,<br />304);<br /> this.bStop1.Name = &quot;bStop1&quot;;<br /> this.bStop1.Size = new System.Drawing.Size(168,<br />24);<br /> this.bStop1.TabIndex = 6;<br /> this.bStop1.Text = &quot;Stop Thread1&quot;;<br /> this.bStop1.Click += new System.EventHandler(this.BStop1Click);<br /> //<br /> // bThread1<br /> //<br /> this.bThread1.Location = new<br />System.Drawing.Point(16, 240);<br /> this.bThread1.Name = &quot;bThread1&quot;;<br /> this.bThread1.Size = new System.Drawing.Size(168,<br />24);<br /> this.bThread1.TabIndex = 1;<br /> this.bThread1.Text = &quot;Start Thread1&quot;;<br /> this.bThread1.Click += new System.EventHandler(this.BThread1Click);<br /> //<br /> // textBox1<br /> //<br /> this.textBox1.Location = new<br />System.Drawing.Point(16, 16);<br /> this.textBox1.Multiline = true;<br /> this.textBox1.Name = &quot;textBox1&quot;;<br /> this.textBox1.ScrollBars = System.Windows.Forms.ScrollBars.Both;<br /> this.textBox1.Size = new System.Drawing.Size(168,<br />184);<br /> this.textBox1.TabIndex = 2;<br /> this.textBox1.Text = &quot;&quot;;<br /> //<br /> // bSuspend2<br /> //<br /> this.bSuspend2.Location = new<br />System.Drawing.Point(216, 272);<br /> this.bSuspend2.Name = &quot;bSuspend2&quot;;<br /> this.bSuspend2.Size = new System.Drawing.Size(168,<br />24);<br /> this.bSuspend2.TabIndex = 8;<br /> this.bSuspend2.Text = &quot;Suspend Thread2&quot;;<br /> this.bSuspend2.Click += new System.EventHandler(this.BSuspend2Click);<br /> //<br /> // bSuspend1<br /> //<br /> this.bSuspend1.Location = new<br />System.Drawing.Point(16, 272);<br /> this.bSuspend1.Name = &quot;bSuspend1&quot;;<br /> this.bSuspend1.Size = new System.Drawing.Size(168,<br />24);<br /> this.bSuspend1.TabIndex = 9;<br /> this.bSuspend1.Text = &quot;Suspend Thread1&quot;;<br /> this.bSuspend1.Click += new System.EventHandler(this.BSuspend1Click);<br /> //<br /> // bResume1<br /> //<br /> this.bResume1.Location = new<br />System.Drawing.Point(16, 336);<br /> this.bResume1.Name = &quot;bResume1&quot;;<br /> this.bResume1.Size = new System.Drawing.Size(168,<br />24);<br /> this.bResume1.TabIndex = 11;<br /> this.bResume1.Text = &quot;Resume Thread1&quot;;<br /> this.bResume1.Click += new System.EventHandler(this.BResume1Click);<br /> //<br /> // bClear1<br /> //<br /> this.bClear1.Location = new<br />System.Drawing.Point(16, 208);<br /> this.bClear1.Name = &quot;bClear1&quot;;<br /> this.bClear1.Size = new System.Drawing.Size(168,<br />24);<br /> this.bClear1.TabIndex = 4;<br /> this.bClear1.Text = &quot;Clear&quot;;<br /> this.bClear1.Click += new System.EventHandler(this.BClear1Cl</p>
<p>ick);<br<br />
 /> //<br /> // bResume2<br /> //<br /> this.bResume2.Location = new<br />System.Drawing.Point(216, 336);<br /> this.bResume2.Name = &quot;bResume2&quot;;<br /> this.bResume2.Size = new System.Drawing.Size(168,<br />24);<br /> this.bResume2.TabIndex = 10;<br /> this.bResume2.Text = &quot;Resume Thread2&quot;;<br /> this.bResume2.Click += new System.EventHandler(this.BResume2Click);<br /> //<br /> // MainForm<br /> //<br /> this.AutoScaleBaseSize = new System.Drawing.Size(5,<br />13);<br /> this.ClientSize = new System.Drawing.Size(408,<br />365);<br /> this.Controls.Add(this.bResume1);<br /> this.Controls.Add(this.bResume2);<br /> this.Controls.Add(this.bSuspend1);<br /> this.Controls.Add(this.bSuspend2);<br /> this.Controls.Add(this.bStop2);<br /> this.Controls.Add(this.bStop1);<br /> this.Controls.Add(this.bClear2);<br /> this.Controls.Add(this.bClear1);<br /> this.Controls.Add(this.textBox2);<br /> this.Controls.Add(this.textBox1);<br /> this.Controls.Add(this.bThread1);<br /> this.Controls.Add(this.bThread2);<br /> this.Name = &quot;MainForm&quot;;<br /> this.Text = &quot;MainForm&quot;;<br /> this.Load += new<br />System.EventHandler(this.MainFormLoad);<br /> this.ResumeLayout(false);<br /> }<br /> #endregion<br /> void BSuspend1Click(object sender, System.EventArgs<br />e)<br /> {<br /> tt1.suspend ();<br /> }<br /> void BResume1Click(object sender, System.EventArgs<br />e)<br /> {<br /> tt1.resume ();<br /> }<br /> void BResume2Click(object sender, System.EventArgs<br />e)<br /> {<br /> tt2.resume ();<br /> }<br /> void BThread1Click(object sender, System.EventArgs<br />e)<br /> {<br /> tt1.start ();<br /> }</p>
<p> void BClear1Click(object sender, System.EventArgs e)<br /> {<br /> textBox1.Text =&quot;&quot;;<br /> }</p>
<p> void BClear2Click(object sender, System.EventArgs e)<br /> {<br /> textBox2.Text =&quot;&quot;;<br /> }</p>
<p> void BThread2Click(object sender, System.EventArgs<br />e)<br /> {<br /> tt2.start ();<br /> }</p>
<p> void BSuspend2Click(object sender, System.EventArgs<br />e)<br /> {<br /> tt2.suspend ();<br /> }</p>
<p> void BStop1Click(object sender, System.EventArgs e)<br /> {<br /> tt1.stop ();<br /> }</p>
<p> void BStop2Click(object sender, System.EventArgs e)<br /> {<br /> tt2.stop ();<br /> }</p>
<p> void MainFormLoad(object sender, System.EventArgs e)<br /> {<br /> //System.Windows.Forms.MessageBox.Show (&quot;Hello&quot;);<br /> }<br /> /*void MainFormClosing(object sender,<br />System.EventArgs e)<br /> {<br /> System.Windows.Forms.MessageBox.Show (&quot;Frnds&quot;);</p>
<p> }*/<br /> void dispose()<br /> {<br /> //System.Windows.Forms.MessageBox.Show (&quot;Closing&quot;);<br /> tt1.stop ();<br /> tt2.stop();<br /> }<br /> }<br />}</p>
<p>/*</p>
<p> Trying to create my own thread;</p>
<p>*/</p>
<p>namespace AObject<br />{<br />public class Thread<br />{<br />private System.Threading.Thread tt;<br />//private ThreadStart ts;<br />private Runnable rr;<br />private bool started;<br />private bool stopped;<br />private bool suspended;</p>
<p>public Thread(Runnable rr)<br />{<br /> this.rr=rr;<br /> started=false;<br /> stopped=true;<br />}<br />public void start()<br />{<br /> if(!started)<br /> {<br /> tt=new System.Threading.Thread(new System.Threading.ThreadStart(rr.run));<br /> tt.Start ();<br /> started=true;<br /> stopped=false;<br /> }<br />}<br />public void stop()<br />{<br /> if (!stopped)<br /> {<br /> resume();<br /> tt.Abort ();<br /> stopped=true;<br /> }<br />}<br />public void suspend()<br />{<br /> if(!suspended&amp;&amp;!stopped)<br /> {<br /> tt.Suspend ();<br /> suspended=true;<br /> }<br />}</p>
<p>public void resume()<br />{<br /> if(suspended&amp;&amp;!stopped)<br /> {<br /> tt.Resume();<br /> suspended=false;<br /> }<br />}<br />public static void sleep(int milliseconds)<br />{<br /> System.Threading.Thread.Sleep(milliseconds);<br />}<br />}<br />public interface Runnable<br />{<br /> void run();<br />}<br />}</p>
<p>public class HelloWorld<br />{<br /> /* public static void Main()<br /> {<br /> }<br /> */<br />}</p>
<p>class PrintHello: AObject.Runnable<br />{<br /> private System.Windows.Forms.TextBox textBox;<br /> private int count;<br /> public PrintHello(System.Windows.Forms.TextBox<br />textBox)<br /> {<br /> this.textBox =textBox;<br /> }<br /> public void run()<br /> {<br /> while(true)<br /> {<br /> textBox.Text =textBox.Text + &quot;\r\n&quot; + &quot;Hello&quot; +<br />++count;<br /> AObject.Thread.sleep(100);<br /> }<br /> }<br />}<br /></span></span></p>
]]></content:encoded>
			<wfw:commentRss>http://www.csharphelp.com/2007/07/multithreading-made-easier-in-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Conversion of Singlethreaded C# Class to Multithreaded One</title>
		<link>http://www.csharphelp.com/2007/04/conversion-of-singlethreaded-c-class-to-multithreaded-one/</link>
		<comments>http://www.csharphelp.com/2007/04/conversion-of-singlethreaded-c-class-to-multithreaded-one/#comments</comments>
		<pubDate>Fri, 06 Apr 2007 04:01:01 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[C# Language]]></category>
		<category><![CDATA[Threading]]></category>

		<guid isPermaLink="false">http://www.csharphelp.com.php5-3.dfw1-2.websitetestlink.com/?p=505</guid>
		<description><![CDATA[AmThreader_demo.zip &#160; Terms definition Multithreaded class &#8211; sounds very confusing. In fact there is no such a thing as singlethreaded or multithreaded class, on the other hand I do not have better name for the construction I have created. Perhaps, I can name it a Thread Isolator.&#160; AmThreader is a code generator that creates a [...]]]></description>
			<content:encoded><![CDATA[<p><span class="smallblack"> </span></p>
<p><span class="smallblack"><img alt="Sample Image - AmThreader.png" src="http://www.csharphelp.com/archives3/files/archive523/AmThreader.jpg" height="471" width="576" /></span></p>
<p><span class="smallblack"><a href="http://www.csharphelp.com/archives3/files/archive523/AmThreader_demo.zip">AmThreader_demo.zip</a></span></p>
<p>&nbsp;</p>
<blockquote><p><span class="smallblack"> </span><br />
<h4><span class="smallblack"> </span></h4>
<h4><span class="smallblack"><span style="color:#ff0000;">Terms definition</span></span></h4>
<p><span class="smallblack"> </span><br />
<h4><span class="smallblack"><span style="font-size:small;">Multithreaded class &#8211; sounds very confusing.<br /> In fact there is no such a thing as singlethreaded or multithreaded class, <br /> on the other hand I do not have better name for the construction I have created.<br /> Perhaps, I can name it a Thread Isolator.&nbsp; </span></span></h4>
<p><span class="smallblack"> </span><br />
<h4><span class="smallblack"><span style="font-size:xx-small;">AmThreader is a code generator that creates a class wrapper for any .NET class (not necessarily C#) <br /> and any call of wrapper class method will be translated to original class call but in a separate thread.</span></span></h4>
<p><span class="smallblack"> </span><br />
<h4><span class="smallblack">Introduction</span></h4>
<p><span class="smallblack"> </span>
<p><span class="smallblack">All of us use computers today. You start an application , click controls and at some <br /> moment it stops to respond. Well, the most probable cause of it is that the main thread is <br /> unable to exit (or continue) for some reason. What reason? <br /> The reason in fact, can be any : Input-Output can not complete, some network problems, <br /> internal application error and the thread went into endless loop etc. <br /> Very annoying situation, indeed. How can this problem be resolved? The only way to create a <br /> responsive and in a certain sense robust application is to use multithreading. However everything is<br /> at cost because the development of multithreaded applications is more complicated. It involves <br /> threads synchronisation, considerably more complicated debugging and so on. That is <br /> why even reputable companies still use single threading. So, how to simplify the development <br /> of multithreaded software? </span></p>
<p><span class="smallblack"> </span><br />
<h4><span class="smallblack">Code Generator</span></h4>
<p><span class="smallblack"> </span>
<p><span class="smallblack">The answer is AmThreader &#8211; the code generator.It converts any singlethreaded .NET class to multithreaded one.<br /> How it works?</span></p>
<p><span class="smallblack"> </span>
<p><span class="smallblack">Let&#39;s look first into the stages of the development of simple multithreaded <br /> application . What are the components of multithreading? <br /> Nothing in fact is really special: <br /> <strong>1</strong>. Temporary variables for holding and passing the parameters from one thread to another. <br /> <strong>2</strong>. A new thread (worker thread). <br /> <strong>3</strong>. Methods to invoke certain methods in the worker thread. <br /> <strong>4</strong>. A loop that runs in the worker thread . <br /> <strong>5</strong>. A bunch of enums ,switches and cases that control the work flow in the worker thread. <br /> <strong>6</strong>. Wait procedure (or extra thread). <br /> <strong>7</strong>. Threads synchronisation components (depend on OS and used language). <br /> <strong>8</strong>. Exception handling. </p>
<p> For instance we have a class ClassA that has the method DoSomething() which may not return. <br /> </span></p>
<p><span class="smallblack"><br />
<table style="height:216px;" border="1" cellspacing="0" width="745">
<tbody>
<tr>
<td bgcolor="#fbf3ec" height="194" width="739"><span style="color:#6666ff;font-size:x-small;">public</span> <span style="color:#0000ff;font-size:x-small;">class</span><span style="font-size:x-small;"> <br />ClassA <br />{ <br /><span style="color:#0000ff;">public</span> ClassA() <br />{ <br /> <span style="color:#0000ff;">public void</span> DoSomething(int b) <br />{ <br />// do something <br />} <br /> }<br />}</span></td>
</tr>
</tbody>
</table>
<p> Let&#39;s convert it to multithreaded one in order to make the application safe and friendly. Speaking in C# <br /> terms this new class can be represented with a snippet below: </p>
<table border="1" cellspacing="0" width="648">
<tbody>
<tr>
<td bgcolor="#fbf3ec" width="642">
<p><span style="color:#0000ff;">namespace</span> SomeNameSpace <br />{ <br /><span style="color:#0000ff;">public class</span> __ClassA <br />{ <br /><span style="color:#0000ff;">private enum </span>Commands_enums <br />{ <br />ClassA__enum_0, <br />DoSomething__enum_1<br />} <br /><span style="color:#0000ff;">private</span> Commands_enums CurrCommand; <br /><span style="color:#0000ff;">private</span> <span style="color:#0000ff;">bool</span> bError; <br /><span style="color:#0000ff;">private</span> <span style="color:#0000ff;">bool</span> ThreadStop; <br /><span style="color:#0000ff;">private</span> ManualResetEvent EventStart = new ManualResetEvent(false); <br /><span style="color:#0000ff;">private</span> <span style="color:#0000ff;">object</span>[] inParams = new object[100]; <br /><span style="color:#0000ff;">private</span> <span style="color:#0000ff;">object</span> ValueParam; <br /><span style="color:#0000ff;">private</span> Thread fThread; <br /><span style="color:#0000ff;">private</span> <span style="color:#0000ff;">int</span> nTimeOut = 10000; <br /><span style="color:#0000ff;">private</span> <span style="color:#0000ff;">int</span> CycleTime = 15; <br /><span style="color:#0000ff;">private</span> ClassA ThreadObjectInstance; </p>
<p><span style="color:#0000ff;">public</span> __ClassA() <br />{ <br />StartThread(); <br />CurrCommand = Commands_enums.ClassA__enum_0; <br />WaitForComplete(); <br />} </p>
<p><span style="color:#0000ff;">public void</span> DoSomething(<span style="color:#0000ff;">int</span> b) <br />{ <br />inParams[0] = b; <br />CurrCommand = Commands_enums.doSomething__enum_1; <br />WaitForComplete(); <br />} </p>
<p>&nbsp;<span style="color:#0000ff;">private void </span>Worker_Thread_01() <br />&nbsp; { <br /><span style="color:#0000ff;">while</span>(!ThreadStop) <br />{ <br />EventStart.WaitOne(); <br /><span style="color:#0000ff;">switch</span>(CurrCommand) <br />{ <br /><span style="color:#0000ff;">case</span> Commands_enums.ClassA__enum_0: <br />ThreadObjectInstance = new ClassA(); <br /><span style="color:#0000ff;">break</span>; </p>
<p><span style="color:#0000ff;">case</span> Commands_enums.DoSomething__enum_1: <br />ThreadObjectInstance.DoSomething((int)inParams[0]); <br /><span style="color:#0000ff;">break</span>; <br />&nbsp; <span style="color:#0000ff;">default</span>: <br /><span style="color:#0000ff;">break</span>; <br />} </p>
<p>&nbsp; <br />bStopWaiting = <span style="color:#0000ff;">true</span>; <br />CurrCommand = Commands_enums.wait_command__enum_; </p>
<p>EventStart.Reset(); </p>
<p>} <br />} </p>
<p><span style="color:#0000ff;">private void</span> StartThread() <br />{ <br />ThreadStart thr_start_func = new ThreadStart (Worker_Thread_01); <br />fThread = new Thread (thr_start_func); <br />fThread.Name = &quot;Worker_Thread_01&quot;; <br />fThread.Start (); //starting the thread <br />} </p>
<p><span style="color:#0000ff;">private void </span>WaitForComplete() <br />{ <br />&nbsp;<span style="color:#0000ff;">int</span> ElapsedTime = 0; <br />EventStart.Set(); <br /><span style="color:#0000ff;">while</span>(!bStopWaiting) <br />&nbsp; { <br />&nbsp; //** Place for event processing <br />ElapsedTime += CycleTime; &nbsp;<br />if (ElapsedTime &gt; nTimeOut) <br />{ <br />bStopWaiting = true; <br />throw new Exception(&quot;Wait TimeOut&quot;); <br />} <br />Thread.Sleep(CycleTime); <br />} <br />} <br />} </p>
<p>} </td>
</tr>
</tbody>
</table>
<p></span>
<p><span class="smallblack">The snippet above is the simplest ,though complete multithreaded class. Yes, it is simple , but what&nbsp;can it do?<br /</p>
<p>> Not mu<br />
ch, the only thing it can do well is waiting for a completion of DoSomething()&nbsp;method and announce <br /> of it&#39;s failure if the worker thread sticks in it. Even with this limited&nbsp;functionality it is useful. The application can <br /> always be terminated gracefully. Although the main&nbsp;thread is still frozen during the execution of DoSomething(). <br /> However for the event driven applications (all GUI or winforms) there is a trick to overcome that unpleasant <br /> effect. We only need to place&nbsp;<span style="color:#0000ff;">Application</span>.DoEvents() inside&nbsp;&nbsp; Wait loop. The interface will still be <br /> responding during doSomething().&nbsp;The code line Thread.Sleep(CycleTime) controls the responsiveness of the <br /> interface.&nbsp;The smaller CycleTime the more responsive the interface is, on the other hand it uses more CPU&nbsp;resources.&nbsp;</p>
<p> How can the new class __ClassA be used? The same way the original class is.&nbsp;</p>
<p> For example :&nbsp;<br /> The original class ClassA can be used in the way something like that : </span></p>
<p><span class="smallblack"><br />
<table style="height:166px;" border="1" cellspacing="0" width="745">
<tbody>
<tr>
<td bgcolor="#fbf3ec">ClassA MyClassA = <span style="color:#0000ff;">new</span> ClassA();<br /><span style="color:#0000ff;">try</span> <br />{<br /> MyClassA.DoSomething(5); <br />} <br /><span style="color:#0000ff;">catch</span>(Exception ex) <br />{ <br />MessageBox.Show(ex.Message); <br />}&nbsp;</td>
</tr>
</tbody>
</table>
<p></span></p></blockquote>
<blockquote><p><span class="smallblack"> </span>
<p lang="cs"><span class="smallblack">How to use the new class? Well , almost the same. The only difference is that the class must be&nbsp; <br /> destroyed explicitly calling Dispose() , otherwise the application will never end with worker thread running. </span></p>
<p><span class="smallblack"><br />
<table style="height:97px;" border="1" cellspacing="0" width="745">
<tbody>
<tr>
<td bgcolor="#fbf3ec">__ClassA MyClassA = <span style="color:#0000ff;">new</span> __ClassA(); <span style="color:#0000ff;">try</span><br />{<br />MyClassA.DoSomething(5); <br />} <br /><span style="color:#0000ff;">catch</span>(Exception ex) <br />{ <br />MessageBox.Show(ex.Message);<br />} <br />MyClassA.Dispose();</td>
</tr>
</tbody>
</table>
<p></span>
<p><span class="smallblack">So, what is so special in __ClassA and how can it be derived (not in the sense of inheritance) from ClassA ? Absolutely <br /> nothing and this operation can be automated completely. </span></p>
<p><span class="smallblack"> </span>
<p><span class="smallblack">Using <span style="color:#0000ff;">Reflection</span> AmThreder generates new class from the Assembly with the same methods names , indexers and properties <br /> as the original class has. Only public methods are processed, even the source code of the original class is no longer needed. </span></p>
<p><span class="smallblack"> </span><br />
<h4><span class="smallblack">Where to download&nbsp; </span></h4>
<p><span class="smallblack"> </span>
<p><span class="smallblack">To download fresh version of AmThreader visit <a href="http://www.amplefile.com/">http://www.amplefile.com/</a> , &quot;<span style="color:#ff33cc;">downloads</span>&quot; page.&nbsp; <br /> AmThreader constantly monitors if fresh version is avalable and will notify you.</span></p>
<p><span class="smallblack"> </span><br />
<h4><span class="smallblack">History</span></h4>
<p><span class="smallblack"> </span>
<p><span class="smallblack">The current version is<span style="color:#0000ff;"> 1.0.2.0&nbsp; </span></span></p>
<p><span class="smallblack"> </span><br />
<h4><span class="smallblack">License</span></h4>
<p><span class="smallblack"> </span>
<p><span class="smallblack">For independent developers AmThreader is free. However it has to be registered</span></p>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.csharphelp.com/2007/04/conversion-of-singlethreaded-c-class-to-multithreaded-one/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Changing the C# Default Limit of 25 Threads of ThreadPool Class</title>
		<link>http://www.csharphelp.com/2007/02/changing-the-c-default-limit-of-25-threads-of-threadpool-class/</link>
		<comments>http://www.csharphelp.com/2007/02/changing-the-c-default-limit-of-25-threads-of-threadpool-class/#comments</comments>
		<pubDate>Thu, 01 Mar 2007 04:01:01 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[C# Language]]></category>
		<category><![CDATA[Threading]]></category>

		<guid isPermaLink="false">http://www.csharphelp.com.php5-3.dfw1-2.websitetestlink.com/?p=469</guid>
		<description><![CDATA[Introduction According to the Microsoft documentation., &#34;The thread pool is created the first time you create an instance of the ThreadPool class. The thread pool has a default limit of 25 threads per available processor, which could be changed using CorSetMaxThreads as defined in the mscoree.h file.&#34; It appears to be a simple function call [...]]]></description>
			<content:encoded><![CDATA[<p><span class="smallblack"><b>Introduction</b><span style="font-size:x-small;">
<p>According to the Microsoft documentation., &quot;The thread pool is created the first time you create an instance of the <b>ThreadPool</b> class. The thread pool has a default limit of 25 threads per available processor, which could be changed using <b>CorSetMaxThreads</b> as defined in the mscoree.h file.&quot;</p>
<p>It appears to be a simple function call to change the default threadlimit of 25 threads of ThreadPool class per processor. But believe meits not that easy at all. I have found the way to do this. But however,if you need more than 25 threads, I would seriously question thearchitecture of the application. The Threadpool is useful for managingthreads that are usually in a wait state and that take only a shortamount of time to do their work. If still you would like to change thedefault limit of 25 threads then here you go.</p>
<p></span>
<li><b>Include header file</b></li>
<p></span></p>
<p><span class="smallblack"><span style="font-size:x-small;">Thefirst problem which I faced as being a VC++ developer is how to include&quot;mscoree.h&quot; header file in C# project. Basically, we can not includeheader files in C# project because C# is purely object orientedprogramming language. The header files are full of constants, whichwouldn?t fit well anyway in this.</span></span></p>
<ol><span class="smallblack"><b>What is the mscorre.h file?</b><span style="font-size:x-small;">
<p>Basically, MSCoree.dll is the Microsoft .NETRuntime Execution Engine, which hosts the .NET CLR (Common LanguageRuntime) in an unmanaged environment, and exposes a generic functions.</p>
<p>Then the main question remains is How to call a unmanaged code(Mscoree.dll functions) from managed code (C# application)? The onlyway to do this is to interop out to unmanaged code and calls theunmanaged interface method to increase the max thread count. </p>
<p></span>
<li><b>What is the interop?</b></li>
<p><span style="font-size:x-small;">
<p>The .Net managed applications can leverageexisting COM components. The COM components inter-operate with the .Netruntime through an interop layer that will handle all the plumbingbetween translating messages that pass back and forth between managedruntime and the COM component operating in the unmanaged realm, andvice versa. Well, as you probably know that the programming model ofCOM and .Net differs greatly. The differences are too great to cover indetail right here. Hence, Its pretty obvious that some form of&quot;Difference Manager&quot; is needed. That?s where COM interop comes intopicture. Because of the COM interop, COM objects become usable from.Net object. COM Interop provides access to existing COM componentswithout requiring that the original component be modified. </p>
<p></span>
<li><b>How to use C# to interoperate with COM objects and its interfaces defined in Mscoree.h file?</b></li>
<p></span></ol>
<p>&lt;dir&gt;&lt;dir&gt;&lt;dir&gt;&lt;dir&gt;
<p><span class="smallblack"><span style="font-size:x-small;">C# uses .NET Framework facilities to perform COM Interop. C# has support for: </span></span></p>
<p>&lt;/dir&gt;&lt;/dir&gt;&lt;/dir&gt;&lt;/dir&gt;
<ul>&lt;dir&gt;&lt;dir&gt;
<ul><span class="smallblack"><span style="font-size:x-small;">
<li>Creating COM objects. </li>
<li>Determining if a COM interface is implemented by an object. </li>
<li>Calling methods on COM interfaces. </li>
<li>Implementing objects and interfaces that can be called by COM clients. </li>
<p></span></span></ul>
<p>&lt;/dir&gt;&lt;/dir&gt;</ul>
<p>&lt;dir&gt;&lt;dir&gt;&lt;dir&gt;&lt;dir&gt;
<p><span class="smallblack"><span style="font-size:x-small;">There are the following steps to create the COM interop for the mscoree.h file and putting all together.</span></span></p>
<p>&lt;/dir&gt;&lt;/dir&gt;&lt;/dir&gt;&lt;/dir&gt;
<ol>
<li>&nbsp;
<ol>
<li>&nbsp;
<ol><span class="smallblack">
<li><span style="font-size:x-small;">Creating a COM Class Wrapper</span><span style="font-size:x-small;"> </span></li>
<li><span style="font-size:x-small;">Declaring a COM coclass</span><span style="font-size:x-small;"> </span></li>
<li><span style="font-size:x-small;">Declaring a COM Interface</span><span style="font-size:x-small;"> </span></li>
<li><span style="font-size:x-small;">Creating a COM Object</span><span style="font-size:x-small;"> </span></li>
<li><span style="font-size:x-small;">Using Casts Instead of QueryInterface</span><span style="font-size:x-small;"> </span></li>
<li><span style="font-size:x-small;">Set Max thread count</span><span style="font-size:x-small;"> </span></li>
<p></span></ol>
</li>
</ol>
</li>
</ol>
<p>&lt;dir&gt;&lt;dir&gt;&lt;dir&gt;&lt;dir&gt;
<p><span class="smallblack"><span style="font-size:x-small;">At first, add empty C# code file called &quot;ICordThread,cs&quot; to C# project.</span></span></p>
<p>&lt;/dir&gt;&lt;/dir&gt;&lt;/dir&gt;
<p><span class="smallblack"><span style="font-size:x-small;">&nbsp;</span></span></p>
<p>&lt;/dir&gt;
<ol>
<li>&nbsp;
<ol>
<li>&nbsp;
<ol><span class="smallblack"><span style="font-size:x-small;">
<li><b>Creating a COM Class Wrapper.</b></li>
<p></span></span>
<p><span class="smallblack"><span style="font-size:x-small;">In ourC# code, to reference COM objects and interfaces defined in Mscoree.hfile, we need to include a .NET Framework definition for the COMinterfaces in our C# build. According to Microsoft documentation, &quot;Theeasiest way to do this is to use TlbImp.exe (Type Library Importer), acommand-line tool included in the .NET Framework SDK. TlbImp converts aCOM type library into .NET Framework metadata ? effectively creating amanaged wrapper that can be called from any managed language. .NETFramework metadata created with TlbImp can be included in a C# buildvia the /R compiler option.&quot;</span></span></p>
<p><span class="smallblack"><span style="font-size:x-small;">Unfortunately, TlbImp.exeutility cannot handle the definitions in the mscoree typelib. Hence, (Iguess) the only one alternative is available i.e. to manually definethe COM definitions in C# source code using C# attributes. Once wecreate the C# source mapping, then we can simply compile the C# sourcecode to produce the managed wrapper for the COM objects defined in themscoree.h file. </span></span></p>
<p><span class="smallblack"><span style="font-size:x-small;">&nbsp;</span></span></p>
<p><span class="smallblack"><span style="font-size:x-small;">
<li><b>Declaring a COM coclass</b></li>
<p></span></span></ol>
</li>
</ol>
</li>
</ol>
<p>&lt;dir&gt;&lt;dir&gt;&lt;dir&gt;&lt;dir&gt;
<p><span class="smallblack"><span style="font-size:x-small;">TheCOM coclass is a COM object. The coclass definition in type libraryenables to list the interfaces and attributes of a COM object. </span></span></p>
<p><span class="smallblack"><span style="font-size:x-small;">The COM coclasses are represented in C# as classes. These classes must have the <b>ComImport </b>attribute associated with them. The following restrictions apply to these classes: </span></span></p>
<p>&lt;/dir&gt;&lt;/dir&gt;&lt;/dir&gt;&lt;/dir&gt;
<ul>&lt;dir&gt;&lt;dir&gt;
<ul><span class="smallblack"><span style="font-size:x-small;">
<li>The class must not inherit from any other class. </li>
<li>The class must implement no interfaces. </li>
<li>The class must also have a <b>Guid</b> attribute that sets the globally unique identifier (GUID) for the class. </li>
<p></span></span></ul>
<p>&lt;/dir&gt;&lt;/dir&gt;</ul>
<p>&lt;dir&gt;&lt;dir&gt;&lt;dir&gt;&lt;dir&gt;
<p><span class="smallblack"><span style="font-size:x-small;">Add the following declaration of coClass to &quot;ICordThread.cs&quot; file</span></span></p>
<p><span class="smallblack"><span style="font-family:Courier New;color:#008000;font-size:x-small;">
<p>// Declare ThreadManager as a COM coclass:</p>
<p></span></span>
<p><span class="smallblack"><span style="font-family:Courier New;font-size:x-small;">	[</span></span></p>
<p><span class="smallblack"><span style="font-family:Courier New;font-size:x-small;">		</span><span style="font-family:Courier New;color:#008000;font-size:x-small;">// CLSID_CorRuntimeHost from MSCOREE.DLL</span></span></p>
<p><span class="smallblack"><span style="font-family:Courier New;font-size:x-small;">		Guid(&quot;CB2F6723-AB3A-11D</p>
<p>2-9C40-0<br />
0C04FA30A3E&quot;),ComImport</span></span></p>
<p><span class="smallblack"><span style="font-family:Courier New;font-size:x-small;">	]</span></span></p>
<p><span class="smallblack"><span style="font-family:Courier New;font-size:x-small;">	</span><span style="font-family:Courier New;color:#0000ff;font-size:x-small;">class</span><span style="font-family:Courier New;font-size:x-small;"> ThreadManager </span><span style="font-family:Courier New;color:#008000;font-size:x-small;">// Cannot have a base class or</span></span></p>
<p><span class="smallblack"><span style="font-family:Courier New;font-size:x-small;">		</span><span style="font-family:Courier New;color:#008000;font-size:x-small;">// interface list here.</span></span></p>
<p><span class="smallblack"><span style="font-family:Courier New;font-size:x-small;">	{ </span></span></p>
<p><span class="smallblack"><span style="font-family:Courier New;font-size:x-small;">		</span><span style="font-family:Courier New;color:#008000;font-size:x-small;">// Cannot have any members here </span></span></p>
<p><span class="smallblack"><span style="font-family:Courier New;font-size:x-small;">		</span><span style="font-family:Courier New;color:#008000;font-size:x-small;">// NOTE that the C# compiler will add a default constructor</span></span></p>
<p><span class="smallblack"><span style="font-family:Courier New;font-size:x-small;">		</span><span style="font-family:Courier New;color:#008000;font-size:x-small;">// for you (no parameters).</span></span></p>
<p><span class="smallblack"><span style="font-family:Courier New;font-size:x-small;">
<p>	}</p>
<p></span></span>
<p><span class="smallblack"><span style="font-size:x-small;">TheComImport attribute marks the class as an externally implemented Comclass. Such a class declaration enables the use of a C# name to referto a COM class. </span></span></p>
<p><span class="smallblack"><span style="font-size:x-small;">The above code declares a class ThreadManager as a class imported from COM that has a CLSID of &quot;</span><span style="font-family:Courier New;font-size:x-small;">CB2F6723-AB3A-11D2-9C40-00C04FA30A3E</span><span style="font-size:x-small;">&quot;. Instantiating a ThreadManager instance causes a corresponding COM instantiation. </span></span></p>
<p>&lt;/dir&gt;&lt;/dir&gt;&lt;/dir&gt;&lt;/dir&gt;
<ol>
<li>&nbsp;
<ol>
<li>&nbsp;
<ol><span class="smallblack"><span style="font-size:x-small;">
<li><b>Declaring a COM Interface</b></li>
<p></span></span></ol>
</li>
</ol>
</li>
</ol>
<p>&lt;dir&gt;&lt;dir&gt;&lt;dir&gt;&lt;dir&gt;
<p><span class="smallblack"><span style="font-size:x-small;">COM interfaces are represented in C# as interfaces with <b>ComImport</b> and <b>Guid</b>attributes. They cannot include any interfaces in their base interfacelist, and they must declare the interface member functions in the orderthat the methods appear in the COM interface.</span></span></p>
<p><span class="smallblack"><span style="font-size:x-small;">COM interfaces declared inC# must include declarations for all members of their base interfaceswith the exception of members of <b>IUnknown</b> and <b>IDispatch</b> ? the .NET Framework automatically adds these. </span></span></p>
<p><span class="smallblack"><span style="font-size:x-small;">By default, the .NETFramework provides an automatic mapping between the two styles ofexception handling for COM interface methods called by the .NETFramework. </span></span></p>
<p>&lt;/dir&gt;&lt;/dir&gt;&lt;/dir&gt;&lt;/dir&gt;
<ul>&lt;dir&gt;&lt;dir&gt;
<ul><span class="smallblack"><span style="font-size:x-small;">
<li>The return value changes tothe signature of the parameter marked retval (void if the method has noparameter marked as retval). </li>
<li>The parameter marked as retval is left off of the argument list of the method. </li>
<p></span></span></ul>
<p>&lt;/dir&gt;&lt;/dir&gt;</ul>
<p>&lt;dir&gt;&lt;dir&gt;&lt;dir&gt;&lt;dir&gt;
<p><span class="smallblack"><span style="font-size:x-small;">Any non-success return value will cause a <b>System.COMException</b> exception to be thrown.</span></span></p>
<p><span class="smallblack"><span style="font-size:x-small;">The following code shows aCOM interface declared interface declared in C# (note that the methodsuse the COM error-handling approach). </span></span></p>
<p><span class="smallblack"><span style="font-size:x-small;">The ICorThreadpool interfaceis documented (prototypes only) in mscoree.h, but is not made availablefrom mscoree.tlb. So the following interop stub lets us get our handson the interface in order to query/control the CLR-managed thread pool.Because we are interested in adjusting maximum thread count of thethread pool configuration, most of the members are actually invalid andcannot be called in their current form.</span></span></p>
<p><span class="smallblack"><span style="font-size:x-small;">Add the following code to &quot;ICordThread.cs&quot; file</span></span></p>
<p><span class="smallblack"><span style="font-family:Courier New;color:#008000;font-size:x-small;">
<p>// derives from IUnknown interface:</p>
<p></span></span>
<p><span class="smallblack"><span style="font-family:Courier New;font-size:x-small;">[</span></span></p>
<p><span class="smallblack"><span style="font-family:Courier New;font-size:x-small;">	// IID_IcorThreadPool</span></span></p>
<p>&lt;dir&gt;&lt;dir&gt;
<p><span class="smallblack"><span style="font-family:Courier New;font-size:x-small;">Guid(&quot;84680D3A-B2C1-46e8-ACC2-DBC0A359159A&quot;), </span></span></p>
<p>&lt;/dir&gt;&lt;/dir&gt;
<p><span class="smallblack"><span style="font-family:Courier New;font-size:x-small;">		InterfaceType(ComInterfaceType.InterfaceIsIUnknown)</span></span></p>
<p><span class="smallblack"><span style="font-family:Courier New;font-size:x-small;">	] </span></span></p>
<p><span class="smallblack"><span style="font-family:Courier New;font-size:x-small;">	</span><span style="font-family:Courier New;color:#0000ff;font-size:x-small;">public</span><span style="font-family:Courier New;font-size:x-small;"> </span><span style="font-family:Courier New;color:#0000ff;font-size:x-small;">interface</span><span style="font-family:Courier New;font-size:x-small;"> ICorThreadpool </span><span style="font-family:Courier New;color:#008000;font-size:x-small;">// Cannot list any base interfaces here </span></span></p>
<p><span class="smallblack"><span style="font-family:Courier New;font-size:x-small;">	{ </span></span></p>
<p><span class="smallblack"><span style="font-family:Courier New;font-size:x-small;">		</span><span style="font-family:Courier New;color:#008000;font-size:x-small;">// Note that IUnknown Interface members are NOT listed here:</span></span></p>
<p>&lt;dir&gt;&lt;dir&gt;&lt;dir&gt;&lt;dir&gt;
<p><span class="smallblack"><span style="font-family:Courier New;color:#0000ff;font-size:x-small;">void</span><span style="font-family:Courier New;font-size:x-small;"> RegisterWaitForSingleObject(); </span><span style="font-family:Courier New;color:#008000;font-size:x-small;">// Don?t call. In correct //signature</span></span></p>
<p>&lt;/dir&gt;&lt;/dir&gt;&lt;/dir&gt;&lt;/dir&gt;
<p><span class="smallblack"><span style="font-family:Courier New;font-size:x-small;">		</span><span style="font-family:Courier New;color:#0000ff;font-size:x-small;">void</span><span style="font-family:Courier New;font-size:x-small;"> UnregisterWait(); </span><span style="font-family:Courier New;color:#008000;font-size:x-small;">// Don?t call. In correct signature</span></span></p>
<p><span class="smallblack"><span style="font-family:Courier New;font-size:x-small;">		</span><span style="font-family:Courier New;color:#0000ff;font-size:x-small;">void</span><span style="font-family:Courier New;font-size:x-small;"> QueueUserWorkItem(); </span><span style="font-family:Courier New;color:#008000;font-size:x-small;">// Don?t call. In correct signature</span></span></p>
<p>&lt;dir&gt;&lt;dir&gt;
<p><span class="smallblack"><span style="font-family:Courier New;color:#0000ff;font-size:x-small;">void</span><span style="font-family:Courier New;font-size:x-small;"> CreateTimer(); </span><span style="font-family:Courier New;color:#008000;font-size:x-small;">// Don?t call. In correct signature</span></span></p>
<p><span class="smallblack"><span style="font-family:C</p>
<p>ourier New;color:#0000ff;font-size:x-small;">void</span><span style="font-family:Courier New;font-size:x-small;"> ChangeTimer(); </span><span style="font-family:Courier New;color:#008000;font-size:x-small;">// Don?t call. In correct signature</span></span></p>
<p>&lt;/dir&gt;&lt;/dir&gt;
<p><span class="smallblack"><span style="font-family:Courier New;color:#008000;font-size:x-small;">		</span><span style="font-family:Courier New;color:#0000ff;font-size:x-small;">void</span><span style="font-family:Courier New;font-size:x-small;"> DeleteTimer(); </span><span style="font-family:Courier New;color:#008000;font-size:x-small;">// Don?t call. In correct signature</span></span></p>
<p>&lt;dir&gt;&lt;dir&gt;&lt;dir&gt;&lt;dir&gt;
<p><span class="smallblack"><span style="font-family:Courier New;color:#0000ff;font-size:x-small;">void</span><span style="font-family:Courier New;font-size:x-small;"> BindIoCompletionCallback(); </span><span style="font-family:Courier New;color:#008000;font-size:x-small;">// Don?t call. In correct // signature</span></span></p>
<p><span class="smallblack"><span style="font-family:Courier New;color:#0000ff;font-size:x-small;">void</span><span style="font-family:Courier New;font-size:x-small;"> CallOrQueueUserWorkItem(); </span><span style="font-family:Courier New;color:#008000;font-size:x-small;">// Dont call. In correct //signiture</span></span></p>
<p><span class="smallblack"><span style="font-family:Courier New;color:#0000ff;font-size:x-small;">void</span><span style="font-family:Courier New;font-size:x-small;"> SetMaxThreads( </span><span style="font-family:Courier New;color:#0000ff;font-size:x-small;">uint</span><span style="font-family:Courier New;font-size:x-small;"> MaxWorkerThreads, </span><span style="font-family:Courier New;color:#0000ff;font-size:x-small;">uint</span><span style="font-family:Courier New;font-size:x-small;"> MaxIOCompletionThreads );</span></span></p>
<p><span class="smallblack"><span style="font-family:Courier New;color:#0000ff;font-size:x-small;">void</span><span style="font-family:Courier New;font-size:x-small;"> GetMaxThreads( </span><span style="font-family:Courier New;color:#0000ff;font-size:x-small;">out</span><span style="font-family:Courier New;font-size:x-small;"> </span><span style="font-family:Courier New;color:#0000ff;font-size:x-small;">uint</span><span style="font-family:Courier New;font-size:x-small;"> MaxWorkerThreads, </span><span style="font-family:Courier New;color:#0000ff;font-size:x-small;">out</span><span style="font-family:Courier New;font-size:x-small;"> </span><span style="font-family:Courier New;color:#0000ff;font-size:x-small;">uint</span><span style="font-family:Courier New;font-size:x-small;"> MaxIOCompletionThreads );</span></span></p>
<p><span class="smallblack"><span style="font-family:Courier New;color:#0000ff;font-size:x-small;">void</span><span style="font-family:Courier New;font-size:x-small;"> GetAvailableThreads( </span><span style="font-family:Courier New;color:#0000ff;font-size:x-small;">out</span><span style="font-family:Courier New;font-size:x-small;"> </span><span style="font-family:Courier New;color:#0000ff;font-size:x-small;">uint</span><span style="font-family:Courier New;font-size:x-small;"> AvailableWorkerThreads, </span><span style="font-family:Courier New;color:#0000ff;font-size:x-small;">out</span><span style="font-family:Courier New;font-size:x-small;"> </span><span style="font-family:Courier New;color:#0000ff;font-size:x-small;">uint</span><span style="font-family:Courier New;font-size:x-small;"> AvailableIOCompletionThreads );</span></span></p>
<p>&lt;/dir&gt;&lt;/dir&gt;&lt;/dir&gt;&lt;/dir&gt;
<p><span class="smallblack"><span style="font-family:Courier New;font-size:x-small;">	}</span></span></p>
<p>&lt;/dir&gt;&lt;/dir&gt;&lt;/dir&gt;&lt;/dir&gt;
<p><span class="smallblack"><span style="font-size:x-small;">&nbsp;</span></span></p>
<p>&lt;dir&gt;&lt;dir&gt;&lt;dir&gt;&lt;dir&gt;&lt;dir&gt;
<p><span class="smallblack"><span style="font-size:x-small;">Note how the C# interfacehas mapped the error-handling cases. If the COM method returns anerror, an exception will be raised on the C# side.</span></span></p>
<p>&lt;/dir&gt;&lt;/dir&gt;&lt;/dir&gt;&lt;/dir&gt;&lt;/dir&gt;
<p><span class="smallblack"><span style="font-size:x-small;">&nbsp;</span></span></p>
<ol>
<li>&nbsp;
<ol>
<li>&nbsp;
<ol><span class="smallblack"><span style="font-size:x-small;">
<li><b>Creating a COM Object</b></li>
<p></span></span>
<p><span class="smallblack"><span style="font-size:x-small;">COM coclasses are represented in C# as classes with a parameter less constructor. Creating an instance of this class using the <b>new</b> operator is the C# equivalent of calling <b>CoCreateInstance</b>. Using the class defined above, it is simple to instantiate the ThreadManager class:</span></span></p>
<p><span class="smallblack">public static void Main() <br /> {<br /> // <br /> // Create an instance of a COM coclass &#8211; calls<br /> //<br /> // CoCreateInstance(CB2F6723-AB3A-11D2-9C40-00C04FA30A3E, <br /> // NULL, CLSCTX_ALL, <br /> // IID_IUnknown, &amp;f) <br /> //<br /> // returns null on failure. <br /> // </span>
<p><span class="smallblack"><span style="font-size:x-small;">	 </span><span style="font-family:Courier New;font-size:x-small;">MSCoreeTypeLib.ThreadManager threadManager =</span></span></p>
<p><span class="smallblack"><span style="font-family:Courier New;font-size:x-small;">				</span><span style="font-family:Courier New;color:#0000ff;font-size:x-small;">new</span><span style="font-family:Courier New;font-size:x-small;"> MSCoreeTypeLib.ThreadManager();</span></span></p>
<p><span class="smallblack"><span style="font-family:Courier New;font-size:x-small;">		:</span></span></p>
<p><span class="smallblack"><span style="font-family:Courier New;font-size:x-small;">		:</span></span></p>
<p><span class="smallblack"><span style="font-size:x-small;">
<p>}</p>
<p>&nbsp;</p>
<li><b>Using Casts Instead of QueryInterface</b></li>
<p>A C# coclass is not very useful until you can access aninterface that it implements. In C++ you would navigate an object&#39;sinterfaces using the <b>QueryInterface</b> method on the <b>IUnknown</b>interface. In C# you can do the same thing by explicitly casting theCOM object to the desired COM interface. If the cast fails, then aninvalid cast exception is thrown.</p>
<p>The cast is required since interop shims like CorRuntimeHost cannothave methods, which would be required if it were to advertise that itimplements ICorThreadPool statically).</p>
<p>&nbsp;</p>
<p></span><span style="font-family:Courier New;font-size:x-small;">
<p>MSCoreeTypeLib.ThreadManager threadManager =</p>
<p></span></span>
<p><span class="smallblack"><span style="font-family:Courier New;color:#0000ff;font-size:x-small;">new</span><span style="font-family:Courier New;font-size:x-small;"> MSCoreeTypeLib.ThreadManager();</span></span></p>
<p><span class="smallblack"><span style="font-family:Courier New;color:#008000;font-size:x-small;">
<p>// QueryInterface for the ICorThreadPool interface:</p>
<p></span><span style="font-family:Courier New;font-size:x-small;">
<p>MSCoreeTypeLib.ICorThreadpool ct =</p>
<p></span></span><span class="smallblack">(MSCoreeTypeLib.ICorThreadpool)threadManager;</span>
<p><span class="smallblack"><span style="font-size:x-small;">&nbsp;</span></span></p>
<p><span class="smallblack"><span style="font-size:x-small;">
<li><b>Get/Set Max Thread Count</b></li>
<p></span></span></ol>
</li>
</ol>
</li>
</ol>
<p>&lt;dir&gt;&lt;dir&gt;&lt;dir&gt;&lt;dir&gt;&lt;dir&gt;
<p><span class="smallblack"><span style="font-size:x-small;">The GetMaxThreads and SetMaxThreads methods can be called using above ICorThreadpool interface object ct as shown bellow.</span></span></p>
<p>&lt;/dir&gt;&lt;/dir&gt;&lt;/dir&gt;&lt;/dir&gt;&lt;/dir&gt;
<p><span class="smallblack"><span style="font-family:Courier New;color:#0000ff;font-size:x-small;">&nbsp;</span></span></p>
<p>&lt;dir&gt;&lt;dir&gt;&lt;dir&gt;&lt;dir&gt;
<p><span class="smallblack"><b><span style="font-size:x-small;">Get Max Thread Count</span></b></span></p>
<p><span class="smallblack"><span style="font-family:Courier New;color:#0000ff;font-size:x-small;">uint</span><span style="font-family:Courier New;font-size:x-small;"> maxW</p>
<p>orkerThreads;</span></span></p>
<p><span class="smallblack"><span style="font-family:Courier New;color:#0000ff;font-size:x-small;">uint</span><span style="font-family:Courier New;font-size:x-small;"> maxIOThreads;</span></span></p>
<p><span class="smallblack"><span style="font-family:Courier New;font-size:x-small;">ct.GetMaxThreads(</span><span style="font-family:Courier New;color:#0000ff;font-size:x-small;">out</span><span style="font-family:Courier New;font-size:x-small;"> maxWorkerThreads, </span><span style="font-family:Courier New;color:#0000ff;font-size:x-small;">out</span><span style="font-family:Courier New;font-size:x-small;"> maxIOThreads);</span></span></p>
<p><span class="smallblack"><span style="font-size:x-small;">IfICorThreadPool.GetMaxThreads returns 25 and 25, then that&#39;s a total of50 threads (as opposed to saying there are 25 threads max, of which upto 25 can be devoted to I/O )</span></span></p>
<p>&lt;/dir&gt;&lt;/dir&gt;&lt;/dir&gt;&lt;/dir&gt;&lt;dir&gt;&lt;dir&gt;
<ol><span class="smallblack"><span style="font-size:x-small;">
<li><b>Set Max Thread Count</b></li>
<p></span><span style="font-family:Courier New;font-size:x-small;">
<p>maxWorkerThreads = 35;</p>
<p>maxIOThreads = 35;</p>
<p>ct.SetMaxThreads(maxWorkerThreads, maxIOThreads);</p>
<p>&nbsp;</p>
<p></span><b><span style="font-size:x-small;">
<li>Putting all together</li>
<p></span></b></span></ol>
<p>&lt;/dir&gt;&lt;/dir&gt;&lt;dir&gt;
<p><span class="smallblack"><span style="font-size:x-small;">This sample program demonstrates how to change the max thread count for the CLR-managed thread pool at runtime.</span></span></p>
<p><span class="smallblack"><span style="font-size:x-small;">This program uses COM interop to reach out and call MSCOREE. </span></span></p>
<p><span class="smallblack"><span style="font-size:x-small;">This program takes advantageof an interface called ICorThreadpool that is implemented by theruntime. Because this interface is mentioned in mscoree.h, but notdocumented in mscoree.tlb, an explicit interop shim is used. SeeICorThreadPool.cs in this project for details.</span></span></p>
<p><span class="smallblack"><span style="font-size:x-small;">At first this applicationgets and displays the max thread count using GetMaxThreads method ofICorThreadPool interface. Then it sets the max thread count usingSetMaxThreads</span><span style="font-family:Courier New;font-size:x-small;"> </span><span style="font-size:x-small;">method of IcorThreadPool interface.</span></span></p>
<p><span class="smallblack"><span style="font-size:x-small;">It starts the 10 threadsusing .Net Thread pool object. At the end of the code, it again getsthe max thread count using GetMaxThreads method. This time it shoulddisplay the same value which being set by SetMaxThreads method.</span></span></p>
<p><span class="smallblack"><span style="font-size:x-small;">The main purpose of thisarticle is not to test ThreadPool class or its functionality. The onlypurpose of this application is to show how to adjust the max threadcount of the ThreadPool class..</span></span></p>
<p>&lt;/dir&gt;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.csharphelp.com/2007/02/changing-the-c-default-limit-of-25-threads-of-threadpool-class/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>.Net Threading, Part II</title>
		<link>http://www.csharphelp.com/2007/02/net-threading-part-ii/</link>
		<comments>http://www.csharphelp.com/2007/02/net-threading-part-ii/#comments</comments>
		<pubDate>Thu, 15 Feb 2007 04:01:01 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[C# Language]]></category>
		<category><![CDATA[Threading]]></category>

		<guid isPermaLink="false">http://www.csharphelp.com.php5-3.dfw1-2.websitetestlink.com/?p=455</guid>
		<description><![CDATA[This is the second article of two partson dotNet threading. In this second part, I will discuss further thesynchronization objects in the System.Threading dotNet namespace, thread localstorage, COM interoperability and thread states. Intermediate Level This article is written for theintermediate and senior C# developer. Working knowledge of the C# programminglanguage and dotNet framework is assumed. [...]]]></description>
			<content:encoded><![CDATA[<div class="Section1">
<p class="MsoBodyText"><span lang="EN-US"><span class="smallblack">This is the second article of two partson dotNet threading. In this second part, I will discuss further thesynchronization objects in the System.Threading dotNet namespace, thread localstorage, COM interoperability and thread states.</span></span></p>
<p><span class="smallblack"><b><span lang="EN-US">Intermediate Level</span></b></span>
<p class="MsoBodyText"><span lang="EN-US"><span class="smallblack">This article is written for theintermediate and senior C# developer. Working knowledge of the C# programminglanguage and dotNet framework is assumed. The article was written with a Betaversion of VS.NET and associated documentation. Changes, although notanticipated, might occur before final release of VS.NET that invalidateportions of this article. </span></span></p>
<p class="MsoBodyText"><span lang="EN-US"><span class="smallblack">In the first article, I discussed how tocreate threads, thread pools and some of the synchronization objects availablein the System.Threading dotNet namespace. In this second article, I willcomplete my discussion of the synchronization objects and will discuss threadlocal storage, COM interoperability and thread states.</span></span></p>
<p><span class="smallblack"><b><span lang="EN-US">ReaderWriterLock</span></b></span>
<p class="MsoBodyText"><span lang="EN-US"><span class="smallblack">Another popular design pattern introducedas a class in the dotNet framework is the ReaderWriterLock. This class allowsan unlimited amount of read locks or one write lock, but not both. This allowsanyone to read the protected resource, as long as nobody is writing to the protectedresource and allows only one thread to write to the protected resource at anyone time. Listing 1 presents a sample using the ReaderWriterLock class.</span></span></p>
<p class="MsoCaption"><span lang="EN-US"><span class="smallblack">Listing <span>1</span>:ReaderWriterLock Class</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span class="smallblack">using System;</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span class="smallblack">using System.Threading;</span></span></p>
<p class="MsoPlainText"><span lang="EN-US">&lt;!&#8211;[if !supportEmptyParas]&#8211;&gt;<span class="smallblack">&nbsp;&lt;!&#8211;[endif]&#8211;&gt;&lt;o:p&gt;&lt;/o:p&gt;</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span class="smallblack">namespace ConsoleApplication9</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span class="smallblack">{</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span><span class="smallblack">??</span></span><span class="smallblack">class Class1</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span><span class="smallblack">??</span></span><span class="smallblack">{</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span><span class="smallblack">?????</span></span><span class="smallblack">public Class1()</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span><span class="smallblack">?????</span></span><span class="smallblack">{</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span><span class="smallblack">????????</span></span><span class="smallblack">rwlock = new ReaderWriterLock();</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span><span class="smallblack">????????</span></span><span class="smallblack">val = &quot;Writer Sequence Number is 1&quot;;</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span><span class="smallblack">?????</span></span><span class="smallblack">}</span></span></p>
<p class="MsoPlainText"><span lang="EN-US">&lt;!&#8211;[if !supportEmptyParas]&#8211;&gt;<span class="smallblack">&nbsp;&lt;!&#8211;[endif]&#8211;&gt;&lt;o:p&gt;&lt;/o:p&gt;</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span><span class="smallblack">?????</span></span><span class="smallblack">private ReaderWriterLock rwlock;</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span><span class="smallblack">?????</span></span><span class="smallblack">private string val;</span></span></p>
<p class="MsoPlainText"><span lang="EN-US">&lt;!&#8211;[if !supportEmptyParas]&#8211;&gt;<span class="smallblack">&nbsp;&lt;!&#8211;[endif]&#8211;&gt;&lt;o:p&gt;&lt;/o:p&gt;</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span><span class="smallblack">??</span></span><span><span class="smallblack">???</span></span><span class="smallblack">public void Reader()</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span><span class="smallblack">?????</span></span><span class="smallblack">{ </span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span><span class="smallblack">????????</span></span><span class="smallblack">rwlock.AcquireReaderLock(Timeout.Infinite);</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span><span class="smallblack">????????</span></span><span class="smallblack">Console.WriteLine(&quot;Acquired Read Handle: &quot;</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span><span class="smallblack">??????????? </span></span><span class="smallblack">&quot;Value = {0}&quot;, val);</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span><span class="smallblack">????????</span></span><span class="smallblack">Thread.Sleep(1);</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span><span class="smallblack">????????</span></span><span class="smallblack">Console.WriteLine(&quot;Releasing Read Handle&quot;);</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span><span class="smallblack">?????</span></span><span><span class="smallblack">???</span></span><span class="smallblack">rwlock.ReleaseReaderLock();</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span><span class="smallblack">?????</span></span><span class="smallblack">}</span></span></p>
<p class="MsoPlainText"><span lang="EN-US">&lt;!&#8211;[if !supportEmptyParas]&#8211;&gt;<span class="smallblack">&nbsp;&lt;!&#8211;[endif]&#8211;&gt;&lt;o:p&gt;&lt;/o:p&gt;</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span><span class="smallblack">?????</span></span><span class="smallblack">public void Writer()</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span><span class="smallblack">?????</span></span><span class="smallblack">{</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span><span class="smallblack">????????</span></span><span class="smallblack">rwlock.AcquireWriterLock(Timeout.Infinite);</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span><span class="smallblack">????????</span></span><span class="smallblack">Console.WriteLine(&quot;Acquired Write Handle&quot;);</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span><span class="smallblack">????????</span></span><span class="smallblack">int id = rwlock.WriterSeqNum;</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span><span class="smallblack">????????</span></span><span class="smallblack">Console.WriteLine(&quot;Writer Sequence Number &quot;</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span><span class="smallblack">??????????? </span></span><span class="smallblack">&quot;is {0}&quot;, id);</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span><span class="smallblack">????????</span></span><span class="smallblack">Thread.Sleep(1);</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span><span class="smallblack">????????</span></span><span class="smallblack">val = &quot;Writer &quot;;</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span><span class="smallblack">????????</span></span><span class="smallblack">Thread.Sleep(1);</span></span></p>
<p class="MsoPlainText"><span lang="EN-US"><span><span class="smallblack"</p>
<p>>??</p>
]]></content:encoded>
			<wfw:commentRss>http://www.csharphelp.com/2007/02/net-threading-part-ii/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Use C# Thread Local Storage To Pass Thread Specific Data</title>
		<link>http://www.csharphelp.com/2007/01/use-c-thread-local-storage-to-pass-thread-specific-data/</link>
		<comments>http://www.csharphelp.com/2007/01/use-c-thread-local-storage-to-pass-thread-specific-data/#comments</comments>
		<pubDate>Fri, 26 Jan 2007 04:01:01 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[C# Language]]></category>
		<category><![CDATA[Threading]]></category>

		<guid isPermaLink="false">http://www.csharphelp.com.php5-3.dfw1-2.websitetestlink.com/?p=435</guid>
		<description><![CDATA[In an ideal world developers typically createinstance variables and access these via interfaces to hold threadspecific data. There are times however in a multithreaded applicationwhere this is not realistic due to a variety of factors includinginflexible interfaces, legacy code, and the original overall design ofthe application. The .NET framework provides a mechanism to store dataat [...]]]></description>
			<content:encoded><![CDATA[<p><span class="smallblack">In an ideal world developers typically createinstance variables and access these via interfaces to hold threadspecific data. There are times however in a multithreaded applicationwhere this is not realistic due to a variety of factors includinginflexible interfaces, legacy code, and the original overall design ofthe application. The .NET framework provides a mechanism to store dataat a thread level and allows you to access this thread specific dataanywhere this thread exists.</span></p>
<p><span class="smallblack">This specific thread level storage is known asthread local storage or TLS for short. The .NET threading namespaceallows .NET developers to use TLS from within their multi-threadedapplications to store data that is unique to each thread. </span></p>
<p><span class="smallblack">The common language runtime allocates amulti-slot data store array to each process when it is created. Threadscan use data slots inside these data stores to persist and retrieveinformation at a thread level. The access methods used to put data intothese slots and pull data from them accept and return a type of objectand therefore make the use of these data slots very flexible.</span></p>
<p><span class="smallblack">The sample code included demonstrates a simpleapplication that uses these data slots or TLS. We will go over a few ofthe lines to help give you a better understanding of what is happeningwhen we put data on and pull data from TLS.</span></p>
<p><span class="smallblack">Sample Application:<br />The sample codeincludes a console application named TLSSample.exe, which is meant todemonstrate how TLS works. A Manager object is created and begins toloop while calling into the processwork method of an instance of aWorker object. The Worker object then generates a random number, whichrepresents the amount of time the Manager object will sleep beforeagain calling into the Worker object, and places this number on TLS.Next, the manager object pulls this number from TLS and sleeps for thespecified amount of time before calling back into the Worker object. </span></p>
<p><span class="smallblack">We will now look more closely at the code thatspecifically deals with TLS in our sample application in an effort tobetter understand how to utilize TLS. We want to be able to access thedata slot by name and therefore we need to allocate a named data slot.The following line allocates a data slot with the name sleeptime.</span></p>
<p><span class="smallblack"> Thread.AllocateNamedDataSlot(&quot;sleeptime&quot;);<br /></span>
<p><span class="smallblack">Now that we have allocated the data slot weneed to place a thread specific value on it so we can access it later.The code snippet below first gets the thread specific named data slotand then places the rndValue variable on this data slot. It isimportant to note that the Thread.SetData method takes two parametersthe second parameter is a type of object. </span></p>
<p><span class="smallblack">LocalDataStoreSlot myData;<br />myData=Thread.GetNamedDataSlot(&quot;sleeptime&quot;);<br />Thread.SetData(myData, rndValue);<br /></span>
<p><span class="smallblack">Now that we have placed a value on the data slot we need to read it back out from higher up the stack. </span></p>
<p><span class="smallblack">In order to read the value from the data slotwe need to take some similar steps that we took to put the value intothe data slot. The code listed below first gets the named data slot andthen we actually read the data from the named data slot. TheThread.GetData method returns an object so we need to coarse this towhatever data type your application needs, in our case this is aninteger.</span></p>
<p><span class="smallblack">LocalDataStoreSlot myTLSValue;	<br />myTLSValue=Thread.GetNamedDataSlot(&quot;SleepTime&quot;);<br />int tlsValue=(int)Thread.GetData(myTLSValue);<br /></span>
<p><span class="smallblack">Finally, we need to free the data slot that we allocated in the beginning of our application. </span></p>
<p><span class="smallblack">Thread.FreeNamedDataSlot(&quot;sleeptime&quot;); <br /></span>
<p><span class="smallblack">Download <a href="http://www.csharphelp.com/archives2/files/archive452/TLS.zip">TLS.zip</a></span></p>
<p><span class="smallblack">Summary:<br />Thread local storage allows you tostore data that is unique to a thread and whose value is determined atrun time. This type of storage can be very helpful when dealing with anexisting multithreaded application whose interfaces or original designare too inflexible for passing these values another way.</span></p>
<p><span class="smallblack">About the Author:<br /> Doug Doedens is a seniorsoftware consultant living in San Diego specializing in .NET, VisualBasic 6, Java, and enterprise development. Doug can be reached atddoedens@hotmail.com </span></p>
]]></content:encoded>
			<wfw:commentRss>http://www.csharphelp.com/2007/01/use-c-thread-local-storage-to-pass-thread-specific-data/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

