chrisn

chrisn
- Name: [not set]
- Favorite Languages: [not set]
- Website: [not set]
- Location: [not set]
- About Me: [not set]
-
C# Tutorial - Using The ThreadPool
06/07/2009 - 14:38
Here's a sample using a queue. I used XElements because my application makes calls to external web services but you could enqueue a text file or objects.
using System;
using System.Collections.Generic;
using System.Xml.Linq;
namespace QueueDemo
{
class Program
{
static int numthreads = 25;
static Queue<XElement> inputqueue;
static XElement[] inputArray;
static XElement[] resultArray;
static System.Threading.ManualResetEvent[] resetEvents;
static void Main(string[] args)
{
inputqueue = new Queue<XElement>();
LoadQueue();
while (inputqueue.Count != 0)
{
// if there are fewer records to process than threads then reduce the thread count
if (inputqueue.Count < numthreads)
{
numthreads = inputqueue.Count;
}
inputArray = new XElement[numthreads];
resultArray = new XElement[numthreads];
resetEvents = new System.Threading.ManualResetEvent[numthreads];
for (int s = 0; s < numthreads; s++)
{
if (inputqueue.Count == 0)
{
break;
}
else
{
// deenque the request
XElement request = inputqueue.Dequeue();
// add an Id to the node so DoWork knows which reset event to trigger
request.Add(new XElement("ThreadId", s));
inputArray[s] = request;
resetEvents[s] = new System.Threading.ManualResetEvent(false);
System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(DoWork), inputArray[s]);
}
}
System.Threading.WaitHandle.WaitAll(resetEvents);
for (int i = 0; i < numthreads; i++)
{
// do something with the result depending on status
switch (resultArray[i].Element("Result").Value)
{
case "false":
Console.WriteLine("Failure");
break;
case "true":
Console.WriteLine("Success");
break;
default:
Console.WriteLine("Error");
break;
}
}
}
Console.ReadLine();
}
static void LoadQueue()
{
// generate 50 test requests and add them to the inputqueue
List<XElement> requests = new List<XElement>();
for (int i = 0; i < 50; i++)
{
// the requests could be anything, in my case they are XML used to make requests to an external web service
inputqueue.Enqueue(new XElement("Request", new XElement("Parameter1", "valueA"), new XElement("Parameter2", "valueB")));
}
}
static void DoWork(object o)
{
XElement request = (XElement)o;
// call external service and set result array to response based on threadid
resultArray[Int32.Parse(request.Element("ThreadId").Value)]
= new XElement("Response", new XElement("Result", Int32.Parse(request.Element("ThreadId").Value) < 12 ? true : false)); // simulate response
// get the threadid and reset
resetEvents[Int32.Parse(request.Element("ThreadId").Value)].Set();
}
}
} -
C# Tutorial - Using The ThreadPool
05/05/2009 - 02:09
I use a System.Collections.Generic.Queue to hold pending requests. In my case I'm processing records from a .csv file so I load each row into an object and insert the object into the queue. I then use a While loop that runs until the queue is empty. Each iteration of the loop spawns 50 threads that deenqueue the requests and make the appropriate calls to DoWork. Let me know if you need a code sample and I will throw something together.
You might also want to check out this article on MSDN:
http://msdn.microsoft.com/en-us/magazine/dd419664.aspx
It's not 100% relevant but might give you some ideas.
-
C# Tutorial - Using The ThreadPool
04/27/2009 - 14:17
Answer to question "How do you get rid of the array "resetEvents" and create a single "doneEvent" event?"
I haven't used this code in a production enviroment but it seems to work OK.
using System;
using System.Threading;
namespace ThreadPoolTest
{
class Program
{
private static int numBusy = 100;
private const int NumThreads = 100;
private static ManualResetEvent doneEvent;
private static void Main(string[] args)
{
doneEvent = new ManualResetEvent(false);
for (int s = 0; s < NumThreads; s++)
{
ThreadPool.QueueUserWorkItem(
new WaitCallback(DoWork), (object)s);
}
doneEvent.WaitOne();
}
private static void DoWork(object o)
{
try
{
// do work here
int index = (int)o;
Console.WriteLine(index);
Console.WriteLine("numbusy {0}: ", numBusy);
}
catch
{
// error handling goes here
}
finally
{
if (Interlocked.Decrement(ref numBusy) == 0)
{
doneEvent.Set();
}
}
}
}
}
Recent Comments