Sending Email Over SMTP Limit - c#

I maintain the website for a small organization with roughly 100 to 120 members.
Every month, we send out an email notifying our members of the topics we will cover in the upcoming meetings.
I am trying to use our website to give us a way to send these emails out, but our ASP Hosting Site has a defined limit of 50 emails per hour.
Theoretically, I suppose I could put the thread to sleep for 1-minute after each SmtpClient.Send(MailMessage) call by using a Thread.Sleep(60000), like this:
public const int ONE_MINUTE = 60000;
public String SiteEmailAddress { get; set; }
public String SiteMailServer { get; set; }
public String SiteMailUserId { get; set; }
public String SiteMailPwd { get; set; }
public void BulkEmail(String emailMessage) {
using (var msg = new MailMessage()) {
msg.From = new MailAddress(SiteMailAddress);
msg.Body = emailMessage;
msg.DeliveryNotificationOptions = DeliveryNotificationOptions.OnFailure;
using (var server = new SmtpClient(SiteMailServer, 25)) {
server.Credentials = new NetworkCredential(SiteMailUserId, SiteMailPwd);
foreach (var person in Personnel.GetActiveMembers()) {
var msgTo = person.PersonalEmail;
if (!String.IsNullOrEmpty(msgTo)) {
msg.To.Clear();
msg.To.Add(new MailAddress(msgTo, person.FullName));
server.Send(msg);
System.Threading.Thread.Sleep(ONE_MINUTE);
}
}
}
}
}
That would either make our website appear dead for over an hour while this ran or it would likely fail.
What is a simple solution for doing this?

Don't use your web server to send emails.
Let a mail sending API handle it for you. This isn't the place to recommend a specific product, so I won't.
If you are going to trickle emails out through your web server, don't do it on the web thread. Store your email-sending status in the database and send one at a time, do it on a separate thread, or use a separate app.

Based on your case I would suggest some solutions:
1- Schedule a task to run every 1.2 min for example, and this task will call the email sender method, and not need to use the Sleep.
Example of how to schedule tasks in asp.net website: http://www.hanselman.com/blog/HowToRunBackgroundTasksInASPNET.aspx
Best way to run scheduled tasks
http://hangfire.io/
2- Add a new task in the windows task scheduler manually or using code (if your hosting allow this), and make this task to call a page in your website which sends the email.
3- Create a separate application in a separate thread which handle the email sending process without affecting your main website performance (this could be a windows service, console app, or normal windows app).

If you're determined to send the emails from your web server, you can use Background Tasks in ASP.NET. Scott Hanselman did a nice write up about it.. You could have it process 50 at a time then wait the remainder of the hour before continuing or wait 72 seconds between each email so that you're sending at most 50 an hour.

We use sendgrid to send emails for our site it has a free monthly limit of 12,000
https://sendgrid.com/free might be an easier alternative?

First of all creating background thread and put it to sleep does not kill application in any way. It will just take thread from thread pool and lock it till operation complete and than dispose it.
Though this can be issue on high traffic applications and limited thread pool, where multiple requests must be handled on same time. Another thing to consider is with each application shutdown, this task get canceled if running. But if that is not issue for you and you want a simple solution, that is.
I would recommend rather use of external API to let it handle for you.

Related

MVC 5 Shared Long Running Task

I have a long running action/method that is called when a user clicks a button on a internal MVC5 application. The button is shared by all users, meaning a second person can come in and click it seconds after it has been clicked. The long running task is updating a shared task window to all clients via SignalR.
Is there a recommended way to check if the task is still busy and simply notifying the user it's still working? Is there another recommended approach? (can't use external windows service for the work)
Currently what I am doing seems like a bad idea or I could be wrong and it's feasible. See below for a sample of what I am doing.
public static Task WorkerTask { get; set; }
public JsonResult SendData()
{
if (WorkerTask == null)
{
WorkerTask = Task.Factory.StartNew(async () =>
{
// Do the 2-15 minute long running job
});
WorkerTask = null;
}
else
{
TempData["Message"] = "Data is already being exported. Please see task window for the status.";
}
return Json(Url.Action("Export", "Home"), JsonRequestBehavior.AllowGet);
}
I don't think what you're doing will work at all. I see three issues:
You are storing the WorkerTask on the controller (I think). A new controller is created for every request. Therefore, a new WorkerTask will always be created.
If #1 weren't true, you would still need to wrap the instantiation of WorkerTask in a lock because multiple clients could reach the WorkerTask == null check at the same time.
You shouldn't have long running tasks in your web application. The app pool could restart at any time killing your WorkerTask.
If you want to skip the best practices advice of "don't do long running work in your web app", you could use the HostingEnvironment.QueueBackgroundWorkItem introduced in .NET 4.5.2 to kick off the long running task. You could store a variable in the HttpApplication.Cache to indicate whether the long running process has been kicked off.
This solution has more than a few issues (it won't work in a web farm, the app pool could die, etc.). A more robust solution would be to use something like Quartz.net or Hangfire.

How do you loop in C# until a new email has arrived?

using System;
using Limilabs.Mail;
using Limilabs.Client.POP3;
class Program
{
static void Main(string[] args)
{
using (System.IO.StreamWriter file = new System.IO.StreamWriter(#"C:\Users\*******\Desktop\WriteLines.txt", true)){
using (Pop3 pop3 = new Pop3())
{
Console.WriteLine("Connecting...");
pop3.ConnectSSL("pop3.live.com"); // or ConnectSSL for SSL
pop3.Login("****#live.com", "****");
// Receive all messages and display the subject
MailBuilder builder = new MailBuilder();
foreach (string uid in pop3.GetAll())
{
IMail email = builder.CreateFromEml(
pop3.GetMessageByUID(uid));
file.WriteLine("Header: " + email.Subject);
file.WriteLine("Message: " + email.Text);
}
pop3.Close();
}
}
}
}
So I have this problem where I want to have this program running 24/7; it is still incomplete but this is just to show basic C# retrieving emails and such. How can I have a loop in C# that only gets halted or forced to anything only when a new email arrives in the inbox? I would like the program only to actually do something upon getting an email sent to in in realtime. I know I can go and print out my emails one by one all at once but I want it to be running and only when a new message is received do I want i to do anything. For example idk, if I was to send a message like clean desktop, it would stop and be parsed and if a valid command sequence specified by another program I am going to make, then it will carry out that command and then keep on looping endlessly waiting for another new message. It'll basically be a server running 24/7 that only responds to new emails. That is what I am going for. All help is greatly appreciated.
Pop3 is a polling protocol. It does not allow to inform you that a new mail has arrived. You would have to e.g. the Exchange protocol that supports this afaik. Thus, for POP3 mailboxes, mail programs usually poll for new emails every e.g. 15min. I'd suspect that your POP3-library does not support this directly. Thus, you would have to use a Timer class and poll for new emails.
Documentation for the Timer class can be found in the MSDN library:
http://msdn.microsoft.com/en-us/library/system.timers.timer%28v=vs.110%29.aspx
You would probably want to use a windows service that polls your email inbox.
A similar question was asked about how to do this here. One of the answers provides a good layout in how to do this.
In addition, if you are trying have your website perform this functionality (because you don't have access to install a windows service) you could use Quartz.net highlighted in this question.

C# console app to send email at scheduled times

I've got a C# console app running on Windows Server 2003 whose purpose is to read a table called Notifications and a field called "NotifyDateTime" and send an email when that time is reached. I have it scheduled via Task Scheduler to run hourly, check to see if the NotifyDateTime falls within that hour, and then send the notifications.
It seems like because I have the notification date/times in the database that there should be a better way than re-running this thing every hour.
Is there a lightweight process/console app I could leave running on the server that reads in the day's notifications from the table and issues them exactly when they're due?
I thought service, but that seems overkill.
My suggestion is to write simple application, which uses Quartz.NET.
Create 2 jobs:
First, fires once a day, reads all awaiting notification times from database planned for that day, creates some triggers based on them.
Second, registered for such triggers (prepared by the first job), sends your notifications.
What's more,
I strongly advice you to create windows service for such purpose, just not to have lonely console application constantly running. It can be accidentally terminated by someone who have access to the server under the same account. What's more, if the server will be restarted, you have to remember to turn such application on again, manually, while the service can be configured to start automatically.
If you're using web application you can always have this logic hosted e.g. within IIS Application Pool process, although it is bad idea whatsoever. It's because such process is by default periodically restarted, so you should change its default configuration to be sure it is still working in the middle of the night, when application is not used. Unless your scheduled tasks will be terminated.
UPDATE (code samples):
Manager class, internal logic for scheduling and unscheduling jobs. For safety reasons implemented as a singleton:
internal class ScheduleManager
{
private static readonly ScheduleManager _instance = new ScheduleManager();
private readonly IScheduler _scheduler;
private ScheduleManager()
{
var properties = new NameValueCollection();
properties["quartz.scheduler.instanceName"] = "notifier";
properties["quartz.threadPool.type"] = "Quartz.Simpl.SimpleThreadPool, Quartz";
properties["quartz.threadPool.threadCount"] = "5";
properties["quartz.threadPool.threadPriority"] = "Normal";
var sf = new StdSchedulerFactory(properties);
_scheduler = sf.GetScheduler();
_scheduler.Start();
}
public static ScheduleManager Instance
{
get { return _instance; }
}
public void Schedule(IJobDetail job, ITrigger trigger)
{
_scheduler.ScheduleJob(job, trigger);
}
public void Unschedule(TriggerKey key)
{
_scheduler.UnscheduleJob(key);
}
}
First job, for gathering required information from the database and scheduling notifications (second job):
internal class Setup : IJob
{
public void Execute(IJobExecutionContext context)
{
try
{
foreach (var kvp in DbMock.ScheduleMap)
{
var email = kvp.Value;
var notify = new JobDetailImpl(email, "emailgroup", typeof(Notify))
{
JobDataMap = new JobDataMap {{"email", email}}
};
var time = new DateTimeOffset(DateTime.Parse(kvp.Key).ToUniversalTime());
var trigger = new SimpleTriggerImpl(email, "emailtriggergroup", time);
ScheduleManager.Instance.Schedule(notify, trigger);
}
Console.WriteLine("{0}: all jobs scheduled for today", DateTime.Now);
}
catch (Exception e) { /* log error */ }
}
}
Second job, for sending emails:
internal class Notify: IJob
{
public void Execute(IJobExecutionContext context)
{
try
{
var email = context.MergedJobDataMap.GetString("email");
SendEmail(email);
ScheduleManager.Instance.Unschedule(new TriggerKey(email));
}
catch (Exception e) { /* log error */ }
}
private void SendEmail(string email)
{
Console.WriteLine("{0}: sending email to {1}...", DateTime.Now, email);
}
}
Database mock, just for purposes of this particular example:
internal class DbMock
{
public static IDictionary<string, string> ScheduleMap =
new Dictionary<string, string>
{
{"00:01", "foo#gmail.com"},
{"00:02", "bar#yahoo.com"}
};
}
Main entry of the application:
public class Program
{
public static void Main()
{
FireStarter.Execute();
}
}
public class FireStarter
{
public static void Execute()
{
var setup = new JobDetailImpl("setup", "setupgroup", typeof(Setup));
var midnight = new CronTriggerImpl("setuptrigger", "setuptriggergroup",
"setup", "setupgroup",
DateTime.UtcNow, null, "0 0 0 * * ?");
ScheduleManager.Instance.Schedule(setup, midnight);
}
}
Output:
If you're going to use service, just put this main logic to the OnStart method (I advice to start the actual logic in a separate thread not to wait for the service to start, and the same avoid possible timeouts - not in this particular example obviously, but in general):
protected override void OnStart(string[] args)
{
try
{
var thread = new Thread(x => WatchThread(new ThreadStart(FireStarter.Execute)));
thread.Start();
}
catch (Exception e) { /* log error */ }
}
If so, encapsulate the logic in some wrapper e.g. WatchThread which will catch any errors from the thread:
private void WatchThread(object pointer)
{
try
{
((Delegate) pointer).DynamicInvoke();
}
catch (Exception e) { /* log error and stop service */ }
}
You trying to implement polling approach, where a job is monitoring a record in DB for any changes.
In this case we are trying to hit DB for periodic time, so if the one hour delay reduced to 1 min later stage, then this solution turns to performance bottle neck.
Approach 1
For this scenario please use Queue based approach to avoid any issues, you can also scale up number of instances if you are sending so many emails.
I understand there is a program updates NotifyDateTime in a table, the same program can push a message to Queue informing that there is a notification to handle.
There is a windows service looking after this queue for any incoming messages, when there is a message it performs the required operation (ie sending email).
Approach 2
http://msdn.microsoft.com/en-us/library/vstudio/zxsa8hkf(v=vs.100).aspx
you can also invoke C# code from SQL Server Stored procedure if you are using MS SQL Server. but in this case you are making use of your SQL server process to send mail, which is not a good practice.
However you can invoke a web service, OR WCF service which can send emails.
But Approach 1 is error free, Scalable , Track-able, Asynchronous , and doesn't trouble your data base OR APP, you have different process to send email.
Queues
Use MSMQ which is part of windows server
You can also try https://www.rabbitmq.com/dotnet.html
Pre-scheduled tasks (at undefined times) are generally a pain to handle, as opposed to scheduled tasks where Quartz.NET seems well suited.
Furthermore, another distinction is to be made between fire-and-forget for tasks that shouldn't be interrupted/change (ex. retries, notifications) and tasks that need to be actively managed (ex. campaign or communications).
For the fire-and-forget type tasks a message queue is well suited. If the destination is unreliable, you will have to opt for retry levels (ex. try send (max twice), retry after 5 minutes, try send (max twice), retry after 15 minutes) that at least require specifying message specific TTL's with a send and retry queue. Here's an explanation with a link to code to setup a retry level queue
The managed pre-scheduled tasks will require that you use a database queue approach (Click here for a CodeProject article on designing a database queue for scheduled tasks)
. This will allow you to update, remove or reschedule notifications given you keep track of ownership identifiers (ex. specifiy a user id and you can delete all pending notifications when the user should no longer receive notifications such as being deceased/unsubscribed)
Scheduled e-mail tasks (including any communication tasks) require finer grained control (expiration, retry and time-out mechanisms). The best approach to take here is to build a state machine that is able to process the e-mail task through its steps (expiration, pre-validation, pre-mailing steps such as templating, inlining css, making links absolute, adding tracking objects for open tracking, shortening links for click tracking, post-validation and sending and retrying).
Hopefully you are aware that the .NET SmtpClient isn't fully compliant with the MIME specifications and that you should be using a SAAS e-mail provider such as Amazon SES, Mandrill, Mailgun, Customer.io or Sendgrid. I'd suggest you look at Mandrill or Mailgun. Also if you have some time, take a look at MimeKit which you can use to construct MIME messages for the providers allow sending raw e-mail and doesn't necessarily support things like attachments/custom headers/DKIM signing.
I hope this sets you on the right path.
Edit
You will have to use a service to poll at specific intervals (ex. 15 seconds or 1 minute). The database load can be somewhat negated by checkout out a certain amount of due tasks at a time and keeping an internal pool of messages due for sending (with a time-out mechanism in place). When there's no messages returned, just 'sleep' the polling for a while. I'd would advise against building such a system out against a single table in a database - instead design an independant e-mail scheduling system that you can integrate with.
I would turn it into a service instead.
You can use System.Threading.Timer event handler for each of the scheduled times.
Scheduled tasks can be scheduled to run just once at a specific time (as opposed to hourly, daily, etc.), so one option would be to create the scheduled task when the specific field in your database changes.
You don't mention which database you use, but some databases support the notion of a trigger, e.g. in SQL: http://technet.microsoft.com/en-us/library/ms189799.aspx
If you know when the emails need to be sent ahead of time then I suggest that you use a wait on an event handle with the appropriate timeout. At midnight look at the table then wait on an event handle with the timeout set to expire when the next email needs to be sent. After sending the email wait again with the timeout set based on the next mail that should be sent.
Also, based on your description, this should probably be implemented as a service but it is not required.
I have been dealing with the same problem about three years ago. I have changed the process several times before it was good enough, I tell you why:
First implementation was using special deamon from webhosting which called the IIS website. The website checked the caller IP and then check the database and send emails. This was working until one day, when I got a lot of very dirty emails from the users that I have totally spammed their mailboxes. The drawback of keeping email in database and sending from SMTP email is that there is NOTHING which ensure DB to SMTP transaction. You are never sure if the email has been successfully sent or not. Sending email can be successfull, can failed or it can be false positive or it can be false negative (SMTP client tells you, that the email was not sent, but it was). There was some problem with SMTP server and the server returned false(email not send), but the email was sent. The daemon was resending the email every hour the whole day before the dirty emails appears.
Second implementation: To prevent spamming, I have changed the algorithm, that the email is considered to be sent even if it failed (my email notification was not too important). My first advice is: "Don't launch the deamon too often, because this false negative smtp error makes users upset."
After several month there were some changes on the server and the daemon was not working well. I got the idea from the stackoverflow: bind the .NET timer to the web application domain. It wasn't good idea, because it seems, that IIS can restart application from time to time because of memory leaks and the timer never fires if the restarts are more often then timer ticks.
The last implementation. Windows scheduler every hour fires python batch which read local website. This fire ASP.NET code. The advantage is that time windows scheduler call the the local batch and website reliably. IIS doesn't hang, it has restart ability. The timer site is part of my website, it is still one projects. (you can use console app instead). Simple is better. It just works!
Your first choice is the correct option in my opinion. Task Scheduler is the MS recommended way to perform periodic jobs. Moreover it's flexible, can reports failures to ops, is optimized and amortized amongst all tasks in the system, ...
Creating any console-kind app that runs all the time is fragile. It can be shutdown by anyone, needs an open seesion, doesn't restart automatically, ...
The other option is creating some kind of service. It's guaranteed to be running all the time, so that would at least work. But what was your motivation?
"It seems like because I have the notification date/times in the database that there should be a better way than re-running this thing every hour."
Oh yeah optimization... So you want to add a new permanently running service to your computer so that you avoid one potentially unrequired SQL query every hour? The cure looks worse than the disease to me.
And I didn't mention all the drawbacks of the service. On one hand, your task uses no resource when it doesn't run. It's very simple, lightweight and the query efficient (provided you have the right index).
On the other hand, if your service crashes it's probably gone for good. It needs a way to be notified of new e-mails that may need to be sent earlier than what's currently scheduled. It permanently uses computer resources, such as memory. Worse, it may contain memory leaks.
I think that the cost/benefit ratio is very low for any solution other than the trivial periodic task.

How Implementing a windows service on a server that is hosted with ISP

I am working on an assignment in asp.net to send notification email to users at specific intervals.
But the problem is that since the server is not privately owned i cannot implement a windows service on it.
Any ideas?
There's no reliable way to achieve that. If you cannot install a Windows Service on the host you could write a endpoint (.aspx or .ashx) that will send the email and then purchase on some other site a service which will ping this endpoint at regular intervals by sending it HTTP request. Obviously you should configure this endpoint to be accessible only from the IP address of the provider you purchase the service from, otherwise anyone could send an HTTP request to the endpoint and trigger the process which is probably undesirable.
Further reading: The Dangers of Implementing Recurring Background Tasks In ASP.NET.
There are several ways to get code executing on an interval that don't require a windows service.
One option is to use the Cache class - use one of the Insert overloads that takes a CacheItemRemovedCallback - this will be called when the cache item is removed. You can re-add the cache item with this callback again and again...
Though, the first thing you need to do is contact the hosting company and find out if they already have some sort of solution for you.
You could set up a scheduled task on the server to invoke a program with the desired action.
You can always use a System.Timer and create a call at specific intervals. What you need to be careful is that this must be run one time, eg on application start, but if you have more than one pools, then it may run more times, and you also need to access some database to read the data of your actions.
using System.Timers;
var oTimer = new Timer();
oTimer.Interval = 30000; // 30 second
oTimer.Elapsed += new ElapsedEventHandler(MyThreadFun);
oTimer.Start();
private static void MyThreadFun(object sender, ElapsedEventArgs e)
{
// inside here you read your query from the database
// get the next email that must be send,
// you send them, and mark them as send, log the errors and done.
}
why I select system timer:
http://msdn.microsoft.com/en-us/magazine/cc164015.aspx
more words
I use this in a more complex class and its work fine. What are the points that I have also made.
Signaling the application stop, to wait for the timer to end.
Use mutex and database for synchronize the works.
Easiest solution is to exploit global.asax application events
On application startup event, create a thread (or task) into a static singleton variable in the global class.
The thread/task/workitem will have an endless loop while(true) {...} with your "service like" code inside.
You'll also want to put a Thread.Sleep(60000) in the loop so it doesn't eat unnecessary CPU cycles.
static void FakeService(object obj) {
while(true) {
try {
// - get a list of users to send emails to
// - check the current time and compare it to the interval to send a new email
// - send emails
// - update the last_email_sent time for the users
} catch (Exception ex) {
// - log any exceptions
// - choose to keep the loop (fake service) running or end it (return)
}
Thread.Sleep(60000); //run the code in this loop every ~60 seconds
}
}
EDIT Because your task is more or less a simple timer job any of the ACID type concerns from an app pool reset or other error don't really apply, because it can just start up again and keep trucking along with any data corruption. But you could also use the thread to simply execute a request to an aspx or ashx that would hold your logic.
new WebClient().DownloadString("http://localhost/EmailJob.aspx");

Send SMS at a same point of time

Previously I posted a question regarding multithreading. Actually my intension is to send SMS for 1000 (or more) people at a same point of time (Ex: 12:00 AM sharp) by using c# and asp.net application. Is it ok to choose multithreading concept to achieve this?
That concept do not need Multi Threading ...
That concept is more of a Task Manager / Cron Job
Create an ASPX Script that sees the time and executes the method you need
Set up Task Manager to run this script every xx minutes
Create a method, that fetches the list of persons and send the SMS through an SMS API, and call it, for ex. SendSMSFromList( List usersList, string message ) {}
Now set everything up and you will run this anytime you need (just set it in the ASPX Script)
please, fell free to tell me, if you need any code for this.
edited for having all steps
If you have a hosted solution, in your hosting control panel you have something as Task Schedule that you can set up to run your script page every n minutes, if so please by pass the next steps. If, by other hand, you are running your own server (IIS) then do this first.
Install cUrl for windows from this location and add curl.exe to C:\WINDOWS
Open Task Manager (Control Panel > Administrative Tools > Task Scheduler on win7)
Create a new task like this
Run the command
curl http://localhost/yourApp/taskManager.aspx
with this you just configured your system to run a file, just like if you execute that link in a browser, that will run every 15 minutes.
Now we need to create that taskManager.aspx file
public partial class taskManager : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
DateTime dt = DateTime.Now;
// Run after midnight
if (dt.Hour == 0 && dt.Minute <= 15)
{
Write2Log("Schedule Job Started", LogType.INFO);
SendSMSFromList(
GetUsersList(),
GetSMSMessage());
Write2Log("Schedule Job Finished", LogType.INFO);
}
}
private string GetSMSMessage()
{
// Fetch the text from DB...
return "This is the message content that I will send as SMS";
}
private List<string> GetUsersList()
{
// fetch the list form DB...
return new List<string>();
}
private void SendSMSFromList(List<string> usersList, string message)
{
// send SMS's
foreach (string phoneNr in usersList)
{
// send message
mySMSAPI.Send(phoneNr, message);
}
}
private void Write2Log(string text, LogType type)
{
// Log to a file what's going on...
try
{
string filename = HttpContext.Current.Server.MapPath("") + "\\status.log";
using (StreamWriter sw = new StreamWriter(filename, true)) // open to append
{
// example: 2008-12-17 13:53:10,462 INFO - Schedule Job Finished
string write = String.Format("{0} {1} - {2}",
DateTime.Now,
type.ToString(),
text);
sw.WriteLine(write);
}
}
catch (Exception)
{ }
}
private enum LogType
{ INFO, WARNING, ERROR }
}
Done...
I made everything in just one file for the sake of the example, you should divide things ... but what I was after was to show you the principle of it.
I don't know how you send them sms. But almost all big sms service providers will allow you to send 1000 within 1 seconds.
So Unless you REALLY REALLY REALLY REALLY REALLY REALLY need to be send them all at once, I suggest you just make a loop and send the information to the service provider one at the time.
Depends on how the SMS are actually sent. If you have let's say a web service that sends the SMS you'll end up in querying it 1000 times at one point which won't solve your problem.
To achieve this you need to make sure that the task of sending can be done simultaniously.
EDIT:
Furthermore I agree to astander that that amount of threads won't be healthy for your system at all.
Edit2:
How sharp does this needs to be? Assumeing that hh:mm is enough you'd have 60s to send
your about 1000 sms. This means that you need to send aprox 17 SMS per second. If you share
this to lets say 4 threads then you'd only need to make sure that your sending process /
device can send 4 SMS / s. this should be achievable I guess.
HTH
I dont think that is going to work for you, and creating such a large number of threads is not advised.
Also, see this link
maximum-number-of-threads-in-a-net-app
Does the SMS application allow for send-to-many? Or maybe use different services on various boxes to send these subset of sms. But i think sending such a volume at once will be difficult.
I suspect you'll have some transport issues getting that much data to your SMS provider at exactly that time presuming it is a realtime process.
I'd find a provider capable of doing scheduled sends and then queue up the messages to send at 12AM at my leisure.

Categories