Application of Redis queue in C # to email alerts

Source: Internet
Author: User

Scene

There is a scenario, a mail alert for the Windows service that gets all the users who turn on mailtips, loops over the messages of those users, and sends a service number message. But the problem comes, the user is less than the case, polling time can endure, if the user is more, the user name sorted by the people, receive email reminders message, delay time is very long.

Get ready

C # Redis Practice list,hashtable

Redis Queue of C #

Scheme

1, the producer thread one gets all the users who open the email alert.

2, according to the configuration to determine the number of queues to use, and the capacity of each queue.

3, line Cheng, get the queue is not full, the current user is enqueued. If all the queues are full, suspend 2s, and then regain the queue that is not full, and the user is queued.

4, according to the configuration to open the consumer thread, each thread independent processing logic. Suspends 2s if the obtained user is empty or the current queue is empty. Otherwise, the user's message is pulled through the EWS service, and a reminder is taken.

5. If an error occurs during the acquisition of a user's message, the user is re-entered into the current queue, waiting for the next pull.

Test

Queue

Test code

    /// <summary>    ///Message Queuing Management/// </summary>     Public classmyredisqueuebus:idisposable {/// <summary>        ///Number of Threads/// </summary>        Private int_threadcount; /// <summary>        ///the capacity of Itcode in each thread/// </summary>        Private int_threadcapacity; /// <summary>        ///Threads/// </summary>        Privatethread[] _threads; /// <summary>        ///Producer Threads/// </summary>        PrivateThread _producerthread; /// <summary>        ///Suspend Time/// </summary>        Private Const intWaitseconde = -; /// <summary>        ///Queue name Prefix/// </summary>        Private string_queueprefix; /// <summary>        ///constructor Function/// </summary>        /// <param name= "ThreadCount" >Number of Threads</param>        /// <param name= "threadcapacity" >queue capacity processed per thread</param>        ///  <param name= "Queueprefix" >queue capacity processed per thread</param>         PublicMyredisqueuebus (intThreadCount,intThreadcapacity,stringQueueprefix) {             This. _threadcapacity =threadcapacity;  This. _threadcount =ThreadCount;  This. _queueprefix = Queueprefix +"_{0}"; }        /// <summary>        ///Open producer/// </summary>         Public voidStartproducer () {_producerthread=NewThread (() ={iredisclientfactory Factory=redisclientfactory.instance; Emailalertsdata Emailalertsdata=NewEmailalertsdata (); //White list                string[] Useridswhitearray = TaskGloableParameter.WhiteList.Split (New Char[] {',',',' },
Stringsplitoptions.removeemptyentries); while(true) { //get all users who have email alerts turned onList<emailalerts> lstemails =emailalertsdata.getallstartalerts (Useridswhitearray); //Queue using(Iredisclient client =Factory. Createredisclient (Webconfig.redisserver, Webconfig.redisport)) {client. Password=webconfig.redispwd; Client. Db=Webconfig.redisserverdb; foreach(varIteminchlstemails) { intQueueindex =-1; stringQueueName =string. Format ( This. _queueprefix, Queueindex); for(inti =0; i < _threadcount; i++) {QueueName=string. Format ( This. _queueprefix, i); //If the current queue is not filled, jump out and use the queue to Enqueue if(Client. GetListCount (QueueName) <_threadcapacity) {Queueindex=i; Break; } } //If all the queues are full, suspend 2s wait for the consumer to consume a portion of the data and start over again if(Queueindex = =-1) {thread.spinwait (Waitseconde); //re-fetch queue for(inti =0; i < _threadcount; i++) {QueueName=string. Format ( This. _queueprefix, i); //If the current queue is not filled, jump out and use the queue to Enqueue if(Client. GetListCount (QueueName) <_threadcapacity) {Queueindex=i; Break; } } } Else { //QueueClient. Enqueueitemonlist (QueueName, Jsonconvert.serializeobject (NewMyqueueitem {UserId=Item.itcode, Syncstate=item. Email_syncstate})); } } } } }); _producerthread.start (); } /// <summary> ///Open Consumer/// </summary> Public voidStartcustomer () {_threads=NewThread[_threadcount]; for(inti =0; I < _threads. Length; i++) {_threads[i]=NewThread (Customerrun); _threads[i]. Start (i); } } Private voidCustomerrun (Objectobj) { intThreadindex =Convert.ToInt32 (obj); stringQueueName =string. Format ( This. _queueprefix, Threadindex); Iredisclientfactory Factory=redisclientfactory.instance; while(true) { using(Iredisclient client =Factory. Createredisclient (Webconfig.redisserver, Webconfig.redisport)) {client. Password=webconfig.redispwd; Client. Db=Webconfig.redisserverdb; if(Client. GetListCount (QueueName) >0) { stringResultjson =client. Dequeueitemfromlist (QueueName); //suspend 2s If the obtained result is empty if(string. IsNullOrEmpty (Resultjson)) {thread.spinwait (Waitseconde); } Else { Try { //time consuming business processingMyqueueitem item = jsonconvert.deserializeobject<myqueueitem>(Resultjson); Console.WriteLine ("Threadid:{0},user:{1}", Thread.CurrentThread.ManagedThreadId.ToString (), item. USERID); } Catch(Exception ex) {//If an error occurs, re-queueclient. Enqueueitemonlist (QueueName, Resultjson); } } } Else { //the current queue is empty, hangs 2sthread.spinwait (Waitseconde); } } } } Public voidDispose () {//destroying a thread when releasing resources if( This. _threads! =NULL) { for(inti =0; I < This. _threads. Length; i++) { This. _threads[i]. Abort (); }} GC. Collect (); } }

Main method call

        Static void Main (string[] args)        {                     new Myredisqueuebus (ten ) Mail_reminder_queue " );            Bus. Startproducer ();            Thread.spinwait (+);            Bus. Startcustomer ();            Console.read ();        }
Summarize

By configuration, determine the number of open queues and the number of threads, if the user increases can increase the number of threads, or add a machine to resolve. In this way, you can solve the post-ranked users, through the random distribution queue, have the opportunity to get email reminders in advance, you can shorten the delay time of email reminders. Of course, such a scheme is not perfect, and can only be thought of here now. This idea is written here, and it is hoped to get a better solution.

The Redis queue for C # is used in email reminders

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.