Tuesday 15 June 2010

c# - Fire and forget with async -



c# - Fire and forget with async -

consider code:

public async task<status> sendmessage(message message) { list<imessage> _messagedispatchers = new list<imessage>(); seek { object[] args = new object[] { _message }; imessage endpoint = (imessage)activator.createinstance(type.gettype(_message.agentdllname), args); _messagedispatchers.add(endpoint); foreach (imessage dispatcher in _messagedispatchers) { await task.run(() => dispatcher.sendmessage(_message)); } homecoming await task.run(() => status.success); } grab (exception ex) { logger.log(loggerlevel.error, ex.message); homecoming status.emailsendingfailed; } }

the sendmessage:

public async task<status> sendmessage(outboundmessage outboundmessage) { string strmessage = string.empty; string subject = string.empty; messageservices objservice = new messageservices(); seek { var config = (from smtpconfigurationelement ms in appconfiguration.instance.smtps ms.key == "smtp" select ms).single(); smtpclient smtpclient = new smtpclient(config.host); smtpclient.port = convert.toint32(config.port); smtpclient.enablessl = true; smtpclient.credentials = new networkcredential(config.username, config.password); string[] strtolist = outboundmessage.tolist.split(';'); mailmessage mail service = new mailmessage(); mail.from = new mailaddress(outboundmessage.fromaddress); if (strtolist.length > 0) { (int j = 0; j < strtolist.length; j++) { mail.to.add(strtolist[j]); } } else { _logger.log(loggerlevel.information, "smtp mail service send failed tolist not correct"); homecoming status.failed; } if (!string.isnullorempty(outboundmessage.cclist)) { string[] strcclist = outboundmessage.cclist.split(';'); if (strcclist.length > 0) { (int k = 0; k < strcclist.length; k++) { mail.cc.add(strtolist[k]); } } } if (!string.isnullorempty(outboundmessage.attachments)) { system.net.mail.attachment attachment; attachment = new system.net.mail.attachment(outboundmessage.attachments); mail.attachments.add(attachment); } strmessage = await objservice.replacemessagewithplaceholders(outboundmessage.placeholdervalues, outboundmessage.messagebody); subject = await objservice.replacemessagewithplaceholders(outboundmessage.placeholdervalues, outboundmessage.subject); mail.body = strmessage; mail.subject = subject; mail.isbodyhtml = true; await task.run(() => smtpclient.send(mail)); homecoming status.success; } grab (exception ex) { homecoming status.failed; } }

and phone call sendmessage:

public status marketingemail(outboundmessage _message) { seek { _message.messagecreateddate = system.datetime.now; processor.sendmessage(_message); homecoming status.success; } grab (exception ex) { _logger.log(loggerlevel.error, "error in marketing email" + ex.tostring()); homecoming status.insertfailed; } }

the whole thought create workflow in sending of email lastly task , should fire , forget thing.

now phone call processor.sendmessage(_message) has suggestion this:

because phone call not awaited, execution of current method continues before phone call completed. consider applying 'await' operator result of call.

which valid thing since async & await need used together.

questions:

will current approach work without problem if suggestion ignored? (i asking since still in development stage , can create suggested design changes rather face critical issues later.) what suggested best practice design workflow considering said requirement?

the current approach "work" in sense go on on return status.success; without waiting phone call processor.sendmessage(_message); complete.

however, since phone call fired & forgotten, , sendmessage overload doesn't logging in catch block, run risk of emails failing sent nobody getting notified it.

a mutual approach async email sending this: stash email somewhere else (typically message queue or database), , set separate async process reads queued emails , sends them. if succeeds, flags email sent. if fails, tries 1 time again (up time limit or # of retries), , if gives up, can trigger notification or set flag can checked later.

then code saying "okay, email queued", instead of "okay, email sent". moving actual sending separate process much more reliable.

c# asynchronous

No comments:

Post a Comment