I am making an webpage with asp.net C#.
I want people to log on and enter in quote requests. then the quote request is emailed to all the relevant people to quote (could be 100+ people).
Obviously I can not have the user sit and wait for the 100+ people to be emailed as the webpage will freeze.
I have thought about implementing a backend program on the server. perhapes that checks for a text file or something and when that text file is there. searches the database for any un-emailed quotes. and emails to the relevant people. then marks record as emailed.
But there must be a better way? IS there a que system or something designed to do things like this?
You can use
ThreadPool.QueueUserWorkItem
in a loop to queue your email sending. See http://msdn.microsoft.com/en-us/library/system.threading.threadpool.queueuserworkitem.aspx for info.
I would use something like Microsoft message queue, and then have a task that sweeps the queue periodically.
I'd get the website to push to the queue, as have the queue set-up as persistent so if the box crashes, restarts etc. nothing is lost.
Simple. Just send it. If it freezes more than 0.1 seconds or so you need better hardware and confiuguration.
Have the SMTP class write to a FOLDER On disc, have the locally installed SMTP service use this as pickup directory. Then youre page is done the moment the file is written. Stnadard .NET classes support this setup via a simple configuration setting. Most people never bother to read the documentation, though.
Noo network invovlved, just 100 file generation or so. Or even 10 files with 10 bcc recipients each. Finished.
Generating 10 small files should be fat. if your discs overload get a small SSD ;) They cost near nothing.
All the rest is a lot of programming work and introduces more to watch into your system.
You could combine the two, although it wouldn't be the approach I'd use.
But using your example, you could create a static listener interface to your backend (server) application, and instead of putting a file and check periodically, you could ping your backend operation to start the operation.
Generating 1 email with 100 people in the "To" or "CC" fields should not cause the page to freeze up. Have you actually observed this behavior? If so, check your SMTP configuration, as something sounds amiss.
However, the solution I've seen put into good use, is to have a SQL database that holds all pending messages to be sent out, then have SQL Server run a job every ten minutes to run through that pending table and do the emailing (as opposed to emailing straight from the .NET app).
Related
For a client of mine I am currently building a 'payslip' export. The export has to be emailed to around 90 of their employees. Each email contains a unique attachment with their own payslip in it.
My current solution is to use the SendGrid.Helpers.Mail.MailHelper package to create an email using the CreateSingleTemplateEmail method. I then use the AddAttachment method to include an attachment. Finally, I send the email by using the SendGridClient.SendEmailAsync method.
All of the above logic is in a foreach loop that iterates over all 90 employees. The problem however, is that the first 15 emails are sent instantaneously, after which the API seems to get throttled. The application is built in a simple Azure Static Web App (cheaper). So there's no real possibility for complex solutions, except if we start paying for more complex solutions. Our goal is to keep this on the cheap side.
After around two minutes, the Azure Function times out and it stops sending the emails.
I've been searching the internet for possible solutions, but I haven't really found a good solution that includes attachments.
Do you guys have any suggestions for me, or is this not possible at all?
Thanks!
Thomas
What if you did not send all of the mails from within one function, but make use of the power of Azure Functions and use Queues, basically to implement Queued Load Levelling. Since I do not know your code, I won't come up with an actual example, but basically, you could do the following
Each of the lanes is a function.
The first one is responsible only for retrieving the payslip data (from a database I guess). It iterates over all the employees and writes the data for each employee to a queue.
The second function is triggered by this very queue and generates a PDF from the payslip data for one employee at a time. This PDF along with some metadata is then written to a second queue (or to a blob container, you maybe will have to experiment which one is the most useful for you, they both have their advantages I guess).
Then a third function would be triggered by the second queue (or by the blob storage), generates an email for that one PDF (based on the metadata) and sends it via SendGrid.
This way even if the API throttles (which seems to be unlikely, based on the comments on the question), each executed function would still finish in a time that is not prone to experience a timeout. This also seems to be a more Cloud (or Serverless) native approach to me than doing it all in one function.
I've read a good bit about threading with C#, but to be upfront I haven't done anything in production using it.
I have an application that has to process a bunch of documents and then send the documents via email. This may take 60 seconds to accomplish. I don't want the user of my web application to have to wait for these things to process to move on to other parts of the site.
On a button click the SendEmail function is called. What can I do to this code to make it so that my users can continue browsing the site without discontinuing the processing I need to do within the EmailPDFs function?
[Authorize]
public ActionResult SendEmail(decimal? id, decimal? id2)
{
EmailPDFs(..., ..., ...);
}
Thanks so much!
This is really the kind of thing that message queues are designed to handle. Fire off a message, and a process on a potentially separate server picks it up and processes it. When it's done, it sends a message back to a queue on your server, where a process on your server picks it up and notifies you that it's complete. You then notify your user that the work is finished.
Modern message queue systems can be backed by databases (such as Mongo, MySql, or SQL Server), and are extremely robust. The great thing about them is that they allow you to move long-running or CPU-intensive processes off onto other servers so that your web site remains nice and snappy.
You could try to add multi-threading and parallelism to your web application, by using TaskFactory and all that other stuff (for many folks, this is the route they take), but it doesn't make it very easy to separate your application if you need to, and break those big, resource-hogging pieces off if it becomes necessary.
I urge you to consider a queue-based solution.
Update:
For samples and information on how to implement this type of solution, see the following:
Reliable Messaging with MSMQ and .NET on MSDN
C#: A Message Queuing Service Application on MSDN
Also, consider glancing at this StackOverflow question for a quick crash course on the bare minimimum amount of code required.
A final note: MSMQ is built into certain flavors of Windows, and can be added to it through the Add/Remove Programs feature of the Control Panel. However, how you install it will depend on your specific flavor and version of Windows. A simple Google search will help you to find the appropriate instructions.
Good luck!
This is more about the design/efficiency of the application rather than the syntax - I need to create a process that sends a batch of texts that will be run on a scheduler (automated batches), but I also need to allow an admin to send a batch manually (manual batch) or individual SMS messages (triggered). My initial thought was to build a server-side console application that can be executed with parameters to handle the sending of all texts, but I'm not positive if this would be the best option. I'm a bit worried about conflicts arising with multiple instances of the console app running (which I would obviously need to code for). Any suggestions on the best way to tackle this?
The batches will process one at a time in a loop, which will post the message to the operator (Twilio) and log the message in our database as sent.
It probably depends on your operator. This one has quite a lot of tech samples and docs.
I have written an application that is used company wide. A lot of users have the tendency to leave the application open 24-7. This application is under development constantly as the Marketing department's needs change. Most changes are minor but often times need to be implemented quickly. Salesmen are often away from their desks or on the phone, so an intercom announcement does not always do the trick. The application is housed on a network file share and shortcutted to.
What I envision is something like a message popping up something like "The program will exit for an update in five minutes, please save your changes now." Is there a way to display this message and kick them from the exe remotely? I thought of maybe just having a database value that it checks periodically to see if an update is pending, but that seems like a cheap hack to me.
Your database check is as good as any other; I personally would recommend polling some service to which it subscribes that would do the same thing. If your app connects directly to the database, however, you're probably better off making the check in the database.
You'd be best off going with a ClickOnce deployment method, however. That would require a major architectural change, but would be best in the long run, IMO.
Pity it's not a web application. Deployment would be a snap!
Anyhow what I'd do is this. Make the application log users out after several minutes of inactivity.
Two approaches to unsaved work. Do nothing and therefore they loose it if unsaved when they are inactive and it logs them out.
As they work, a local journal of changes is kept. When they are logged out due to inactivity, logging back will use the journal to open things back up as they were.
EDIT: To prevent users from using the old version. Write a database field with a version or build number. If running version < version in db field then refuse login, and/or restart program to load new image.
You can set up a central server that the .exe sends requests to to find out when updates are available.
I would recommend that you look into WCF as a framework for your solution; there are many great references for the framework as well as posts on sites like this one. You can probably spin up a separate thread in your application that checks for updates every X minutes.
As for your specific question, "Is there way to display this message and kick them from the exe remotely?", yes it is possible, but it is more feasible to make the program automatically query for the update.
If you want to shut them down for update remotely, then you have to know where they are on the network. If the program periodically contacts a central database, then there is no need for the server to know where the program is on the network, the program can automatically reach out to the server from wherever it is.
You could use a messaging system such as RabbitMQ, or any other one, and have the applications listen to a channel in the system. Then an administrative application could send a message to the user applications forcing them to shut down.
If the changes aren't breaking changes, you might want to look at something like ClickOnce which allows you to publish updates to applications while the users are running them, though users will be running old versions of the application until it restarts.
I didn't get what you got stuck on. Just create a timer, and on user interaction, reset the timer, to e.g. 5 minutes. Then, when the timer fires, show the message box, and create another timer, when that one fires, just kill the current process.
Rather tangential answer but if the issue is people leaving workstations up and logged on then take a look at something like nightwatchman from www.1e.com that powers down the PC after x period of inactivity. Sell it to your company as "doing your bit for the environment" and saving wasted electricity costs.
It has become apparent that where I work needs, internally, a "notification system". The issue being that we are very spread out throughout multiple buildings and the bulk of the work force regularly keeps there email closed for hours at a time.
I need to create a simple way to be able to push out a message and have it "pop up" on everyones computer(or a single computer).
My first thought was to write a windows service that calls a winform/wpf app that resides on each computer that simply pops up with the message. Not sure how viable an idea that is but this is just brain-storming.
A different route, I thought, could be an app that resides in the systray on each computer that polls a db table and using the Query Notifications could pop up a message each time a new row is added. Then simply create an insanely basic app for writing a row to that table.
So, what I am asking is if any one else has walked this path. If so, how?
What things did you take into
consideration?
Are either of my ideas valid starting
points or are "egg and my face in
perfect alignment"?
Is there a different way that is even
simpler?
Thanks
Some simple requirements --> Must be "One Way" as I cannot give our user base a "chat" system. Must be, somewhat, hidden so as to discourage users shutting it off. A la system tray or service.
Wouldn't net send save you reinventing the wheel?
I've never done this but I've worked in a call-centre that did use something similar and they're insanely useful. I remember once when everyone got a message saying "does anyone know Mandarin? HELP ME!!" Brilliant. (Luckily someone did.)
Anyway your ideas are perfectly fine. Personally I'd do this as a client/server application. A windows forms or WPF application that sits in the systray could link to a server using a TCP/IP duplex connection using WCF. Perhaps get the client to register to certain groups depending on the department of the PC it's sitting on.
Then when someone wants to send a message they select which group it needs to go to (or all groups), the message hits the server which sends out to all connected clients, and the WPF app on the computer receives the message and pops it up. You don't even need a database except to store the users/groups, and the message history if you need to.
This might be a ridiculous answer but have you considered implementing a chat system? It's simple to implement and well tested.
Here are some possibilities:
http://messenger.softros.com/
http://en.wikipedia.org/wiki/Instant_messaging#User_base
Article on building your own:
http://www.computerworld.com/s/article/9002059/How_to_build_your_own_corporate_IM_system_
The easiest way to do this is to have a simple client on each machine polling a central service for alerts. Each alert should have a unique id so each client can deal with idempotency (you don't want the central service keeping tabs on which clients have "popped up").
I also recommend having a reasonably short lifespan for each alert, so the client only needs to know a very short list of alerts it has displayed and so if a machine was re-started, only a small history of alerts would be displayed.
With 300 subscribers, you'll want the polling to involve a nice long gap too - you don't really want 300 checks every 10 seconds - so you'll have to balance the technical desire for long gaps between checks with the business requirement to get an alert within a certain timeframe.
You could easily achieve this with a NET/TCP WCF service being polled by either a WINFORM / WPF application that is added as a start up program, or a windows service that then spawns a UI to display the notification.
I did something like this a long time ago to coordinate smoke breaks. I simply sent a broadcast packet out on the LAN at a specific port. Worked relatively well, although since anybody could broadcast and everybody would get a popup, it got abused a lot.
I would recommend you SPARK. We have same problem in my firm and finally decided to save time and do not reinventing the wheel and use existing (freeware) solution. SPARK does the job for us.
"Spark is an Open Source, cross-platform IM client optimized for businesses and organizations. It features built-in support for group chat, telephony integration, and strong security. It also offers a great end-user experience with features like in-line spell checking, group chat room bookmarks, and tabbed conversations."
If you cannot use / install existing IMs you might thing about implementing simple "chat" protocol in your app.
It is quite easy do that base on sockets and many articles available.
For example:
http://www.codeproject.com/KB/IP/TCPIPChat.aspx
http://www.codeproject.com/KB/miscctrl/SimpleMessenger.aspx?display=Print
If you need something advanced (eg. receive historical notification, users status management etc) you can consider using openSource Jabber API:
Eg http://www.codeproject.com/KB/gadgets/googletalk.aspx