Consider this code:
public async Task<Status> SendMessage(Message message) { List<IMessage> _messageDispatchers = new List<IMessage>(); try { 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)); } return await Task.Run(() => Status.Success); } catch (Exception ex) { logger.Log(LoggerLevel.Error, ex.Message); return Status.EmailSendingFailed; } } the SendMessage:
public async Task<Status> SendMessage(OutboundMessage outboundmessage) { string strMessage = string.Empty; string subject = string.Empty; MessageServices objService = new MessageServices(); try { var config = (from SmtpConfigurationElement ms in AppConfiguration.Instance.Smtps where 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 = new MailMessage(); mail.From = new MailAddress(outboundmessage.FromAddress); if (strToList.Length > 0) { for (int j = 0; j < strToList.Length; j++) { mail.To.Add(strToList[j]); } } else { _LOGGER.Log(LoggerLevel.Information, "SMTP Mail Send failed as ToList is not correct"); return Status.Failed; } if (!string.IsNullOrEmpty(outboundmessage.CCList)) { string[] strCCList = outboundmessage.CCList.Split(';'); if (strCCList.Length > 0) { for (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)); return Status.Success; } catch (Exception ex) { return Status.Failed; } } And the call to SendMessage:
public Status MarketingEmail(OutboundMessage _message) { try { _message.MessageCreatedDate = System.DateTime.Now; processor.SendMessage(_message); return Status.Success; } catch (Exception ex) { _LOGGER.Log(LoggerLevel.Error, "Error in Marketing Email" + ex.ToString()); return Status.InsertFailed; } } The whole idea is to make a workflow in which sending of the email is the last task and that should be a fire and forget thing.
Now the call to processor.SendMessage(_message) has a suggestion like this:
Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
Which is a valid thing since async & await need to be used together.
Questions:
- Will the current approach work without any trouble if the suggestion is ignored? (I am asking this since this is still in the development stage and I can make the suggested design changes now rather than face any critical issues later.)
- What is the suggested best practice to design a workflow considering the said requirement?
Status.Successa enum? if it is you should not be doingTask.Run(() => Status.Success)doreturn Task.FromResult(Status.Success)or justreturn Status.Success;as approprate, no need to start up a task and wait for it.