Jon schrieb:
Daniel <da****@danielf .chwrote:
I have written a app that gets emails from a DB and checks if it's a
correct email (connects to the remote mailserver and checks the
response).
I would like to improve the performance with using multiple threads.
can I use a threadpool for this? and how do I have to do this.
For starting i have all emailaddresses in a Array.
I would suggest not using the thread pool for this - you could easily
swamp it, which would make other things which try to use it less
responsive.
I would suggest you use a producer/consumer queue, and then you can
"manually" create as many threads as you want to be consumers of the
queue. This would be a sort of threadpool in itself, *just* for this
purpose. You'd have a lot more control over things that way.
See http://www.pobox.com/~skeet/csharp/t...eadlocks.shtml (half
way down) for some sample producer/consumer code.
--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Thanks for the answer.
I was now just playing around with this. Not sure if I understad it
right.
Here What I have:
using System;
using System.Collecti ons;
using System.Threadin g;
public class Test
{
static CheckEmail queue;
public static int rows = 100;
static void Main()
{
queue = new CheckEmail();
new Thread(new ThreadStart(Ema ilChecker)).Sta rt();
new Thread(new ThreadStart(Ema ilChecker)).Sta rt();
new Thread(new ThreadStart(Ema ilChecker)).Sta rt();
new Thread(new ThreadStart(Ema ilChecker)).Sta rt();
new Thread(new ThreadStart(Ema ilChecker)).Sta rt();
Random rng = new Random(0);
for (int i = 0; i < rows; i++)
{
Console.WriteLi ne("Producing {0}", i);
queue.Produce(" Daniel " + i.ToString());
}
while (queue.Count 0)
{
Console.WriteLi ne("There are {0} emails Waiting",
queue.Count);
Thread.Sleep(20 00);
}
//Here I would like to go ahead when all EMails are processed.
}
static void EmailChecker()
{
// Make sure we get a different random seed from the
// first thread
Random rng = new Random(2);
// We happen to know we've only got 10
// items to receive
for (int i = 0; i < rows; i++)
{
object o = queue.EmailChec k();
//Process Email
Console.WriteLi ne("\t\t\t\tCon suming {0}", o);
Thread.Sleep(rn g.Next(1000));
}
}
}
public class CheckEmail
{
readonly object listLock = new object();
Queue queue = new Queue();
private string Recipient;
public int Count
{
get { return queue.Count; }
}
public void Produce(object o)
{
lock (listLock)
{
queue.Enqueue(o );
Recipient = o.ToString();
// We always need to pulse, even if the queue wasn't
// empty before. Otherwise, if we add several items
// in quick succession, we may only pulse once, waking
// a single thread up, even if there are multiple threads
// waiting for items.
Monitor.Pulse(l istLock);
}
}
public object EmailCheck()
{
lock (listLock)
{
// If the queue is empty, wait for an item to be added
// Note that this is a while loop, as we may be pulsed
// but not wake up before another thread has come in and
// consumed the newly added object. In that case, we'll
// have to wait for another pulse.
while (queue.Count == 0)
{
// This releases listLock, only reacquiring it
// after being woken up by a call to Pulse
Monitor.Wait(li stLock);
}
return queue.Dequeue() ;
}
}
}
So I produce the queue with all emailaddresses (200'000) and then walk
trought with 5 Threads (in this exemple).
Then I wait till the que is empty. How do I know if the last Thread has
finished the work?
So I have to Write the emailaddresses in the Function EmailChecker()
back to the database right?
I also have to write the Logfile in the function EmailChecker().
How can I close the Queue to exit correctly?
I want to run this only if somone requests it by pressing the button.
Thanks for your help
Daniel