Link to home
Start Free TrialLog in
Avatar of MohitPandit
MohitPanditFlag for India

asked on

C#: Use Multi-threading to send email or other activity (request for code-snippet)

Hello Folks,

I've a table with 50 hundred records which I need to send as email or sms (daily) through C#.
Instead to use one-by-one to send email, I've two options

1. Async Programming with TPL (Task Parallel Library) using await & async
2. Multi-threading programming in C#

I believe that I should use multi-threading in C# as TPL doesn't do tasks at same time. Right?

Apart, in multi-threading C#, do you have code snippet for below use case in C#?
1. Use Thread-Pool
2. Use configurable threads & chunk size like 2 threads with 5 chunk size, means one thread will handle 5 records at same time
3. Addition, in case any records completed (email sent) by thread out of 5 records. Example, 1 record' email sent then queue next record with same thread. So that thread should not wait to complete all 5 records to finish.

Do you have other thoughts too?

Best Regards,
Mohit Pandit
Avatar of gr8gonzo
Flag of United States of America image

I believe that I should use multi-threading in C# as TPL doesn't do tasks at same time. Right?

Wrong. That's why it's called "parallel" - because it DOES do tasks at the same time.

Async/await are simply easy ways of getting implementing multi-threading. The moment that a piece of code has to wait for something like a network call, the system sets up a separate thread and runs the code on that thread, and it manages all of the overhead for you.

If you want to spin up a thread manually without waiting for the result, you can just use Task.Run() to run a function or bit of code in a separate thread.

Some things to keep in mind:

- your computer does not have unlimited threads so you can't have 10,000 threads all running at the same time. The tasks can be queued up but you will only have as many threads running as your OS and processor combination allows. It's generally not a good idea to try and exhaust those threads, though, unless you really do not care at all about impacting the performance of other applications.

- be careful when sending large volumes of emails directly. You should make sure you're sending them via a local mail relay that can properly limit the rate and also enforce things like DKIM and SPF so your emails don't get marked as spam (and worse, get your IP blacklisted).

- even if sending by mail relay, you should probably still use await to make sure you aren't overloading the mail relay server's resources.

Generally speaking, I would create a lockable queue in memory, then a "FetchNext" method on that queue that returned the next unprocessed item in the queue and returned it to the caller. If all items in the queue are processed, you return null.

Then create a List<> of workers. Each worker, when started, enters a while() loop that continues as long as FetchNext returns a valid item from the queue. Then that worker does it's thing (sends an email or whatever) using the details from the queue item that it fetched, then marks the item as processed and continues to the next iteration of the loop.

Once the loop finishes, the worker stops.

Then add a method to the queue like AddItem so that whenever an item is added to that queue, the method loops through your worker List<> and checks to see if any of them are stopped and if it finds one, then it starts just that one worker and returns.

This way, you can easily control the max number of parallel workers and they only run when there's something in the queue to process. When nothing is in the queue, they stop running, freeing up those threads/resources.
Avatar of MohitPandit


Thanks for details. About Async vs. multi-threading, I read from an article (please find below few lines). But now, I am clear & create a POC using Async & update here.

First, a quick note on terminology: while asynchronous programming and multithreaded programming are often mentioned in the same context, they are not the same thing. Asynchronous programming is a bit more general in that it has to do with latency (something on which your application has to wait, for one reason or another), whereas multithreaded programming is a way to achieve parallelization (one or more things that your application has to do at the same time).
Avatar of gr8gonzo
Flag of United States of America image

Link to home
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Sure, thanks. I'll take this up accordingly.