Project background:
The recent refactoring of a project a few years ago found that sending mail functionality takes a certain amount of time to process, and because the send is synchronous, the subsequent actions cannot be performed when the message is sent
when you actually send a message, you only need to write the results to the system log to have no effect on other businesses, so you decide to change the Send mail operation to an asynchronous because the message class library of C # is used, and C # itself has provided the ability to send asynchronously, changing the method name is not difficult, but it is a bit difficult to write to the log after sending the Send method to SendAsync .because sending mail in the project is a separate component, I can't add write log operations directly in the Send Message Class library (not the same class library, the example on the network and MSDN is under the same component)but C # can use delegates to pass methods as parameters, so I can add a callback method to the method that sends the message, and then execute the callback method after sending the message asynchronously Full code:
/****************************************************************** * Creator: HTL * creation time: 2015-04-16 21:34:25 * Description: C # Send Asynchronous Mail Demo * Email:[email protected] *******************************************************************/usingSystem;usingSystem.Net.Mail;namespacesendasyncemailtest{classProgram {Const stringDateFormat ="yyyy-mm-dd:hh:mm:ss:ffffff"; Static voidMain (string[] args) {Console.WriteLine ("start asynchronous Send message, time:"+DateTime.Now.ToString (DateFormat)); NewMailhelper (). SendAsync ("Send Async Email Test","This is Send Async Email Test","[email protected]", emailcompleted); Console.WriteLine ("message is being sent asynchronously, time:"+DateTime.Now.ToString (DateFormat)); Console.readkey (); Console.WriteLine (); } /// <summary> ///callback method After message is sent/// </summary> /// <param name= "message" ></param> Static voidEmailcompleted (stringmessage) { //1 seconds DelaySystem.Threading.Thread.Sleep ( +); Console.WriteLine (); Console.WriteLine ("Email results: \ r \ n"+ (Message = ="true"?"message sent successfully":"message failed to send") +", Time:"+DateTime.Now.ToString (DateFormat)); //Write Log } } /// <summary> ///Send Message Class/// </summary> Public classMailhelper { Public Delegate intMethoddelegate (intXinty); Private ReadOnly intSmtpport = -; ReadOnly stringSmtpServer ="smtp.xxxx.cn"; Private ReadOnly stringUserName ="[email protected]"; ReadOnly stringPWD ="123456"; Private ReadOnly stringAuthorName ="HTL"; Public stringSubject {Get;Set; } Public stringBody {Get;Set; } Public string[] Tos {Get;Set; } Public BOOLEnablessl {Get;Set; } MailMessage getclient {Get { if(Tos = =NULL)return NULL; MailMessage MailMessage=NewMailMessage (); //Multiple Recipients foreach(stringStrinchTos) { foreach(string_strinchStr. Split (',') {mailMessage.To.Add (_STR); }} Mailmessage.from=NewSystem.Net.Mail.MailAddress (UserName, AuthorName); Mailmessage.subject=Subject; Mailmessage.body=Body; Mailmessage.isbodyhtml=true; Mailmessage.bodyencoding=System.Text.Encoding.UTF8; Mailmessage.subjectencoding=System.Text.Encoding.UTF8; Mailmessage.priority=System.Net.Mail.MailPriority.High; returnMailMessage; }} smtpclient getsmtpclient {Get { return NewSmtpClient {usedefaultcredentials=false, Credentials=NewSystem.Net.NetworkCredential (UserName, PWD), Deliverymethod=System.Net.Mail.SmtpDeliveryMethod.Network, Host=SmtpServer, Port=Smtpport, Enablessl=Enablessl,}; } } //callback Methodaction<string> actionsendcompletedcallback =NULL; ///// <summary> /////Use asynchronous Send mail///// </summary> ///// <param name= "Subject" >Theme</param> ///// <param name= "Body" >content</param> ///// <param name= "to" >recipient, to, separate multiple recipients</param> //// <param name= "_actincompletedcallback" >callback method After message is sent</param> ///// <returns></returns> Public voidSendAsync (stringSubjectstringBodystringTo, action<string>_actincompletedcallback) { if(string. IsNullOrEmpty (To))return; Subject=subject; Body=body; Tos= To. Split (','); Enablessl=false; SmtpClient SmtpClient=getsmtpclient; //Send mail callback methodActionsendcompletedcallback =_actincompletedcallback; Smtpclient.sendcompleted+=NewSendcompletedeventhandler (Sendcompletedcallback); MailMessage MailMessage=getclient; Try{smtpclient.sendasync (MailMessage,"true");//sends a message asynchronously if the parameter in the callback method is not "true" to indicate that the send failed } Catch(Exception e) {Throw NewException (e.message); } finally{smtpclient=NULL; MailMessage=NULL; } } /// <summary> ///Execute callback method after asynchronous operation completes/// </summary> /// <param name= "Sender" ></param> /// <param name= "E" ></param> Private voidSendcompletedcallback (ObjectSender,system.componentmodel.asynccompletedeventargs e) { //The callback method is not required under the same component, so write the log directly here//Write Log//return; if(Actionsendcompletedcallback = =NULL)return; stringMessage =string. Empty; if(e.cancelled) {message="Asynchronous Operation canceled"; } Else if(E.error! =NULL) {Message= (string. Format ("Userstate:{0},message:{1}", (string) E.userstate, e.error.tostring ())); } Elsemessage= (string) E.userstate; //Execute callback methodactionsendcompletedcallback (message); } }}
There's a picture of the truth
Reference:
cnblogs.com Introduction to C # Delegates (delegate, Action, Func, predicate) MSDN Action Delegate MSDN Simpleasynchronousexample "resolved" C # How to pass functions as arguments to other functions
CodeProject.com Send asynchronous Mail using ASP.
From for notes (Wiz)
C # uses system methods to send asynchronous messages