1

I am having web api, which is non async.

From that web api, i am calling method

SmtpClient.SendMailAsync(email);

This email get sent to respective person, but the next web api request get fails.

public class TestController : ApiController
{
    public TestController(TestService testService)
    {
       _testService = testService;
    }

    public IHttpActionResult Post(data)
     {
         _testService.SendEmail(data);
     }
}

public class TestService 
{
    public async Task SendEmail(MailMessage email)
     {
        SmtpClient client = new SmtpClient();
        client.SendMailAsync(email)
     }
}
8
  • Usually there is still a non-Async Method. In this case, SendMail rather then SendMailAsync. Commented Nov 14, 2019 at 5:38
  • replace _testService.SendEmail(data); with _testService.SendEmail(data).GetAwaiter().GetResult() Commented Nov 14, 2019 at 5:48
  • @ravikumar: I don't want to wait till email sent, i want behavior like fire and forget. Commented Nov 14, 2019 at 6:12
  • @HemantMalpote: note, that SmtpClient must be disposed. Wrap it into using. Commented Nov 14, 2019 at 7:46
  • @Dennis : agree Commented Nov 14, 2019 at 8:34

3 Answers 3

1

From the days before the async/await pattern was introduced, there are still many non-asychronous functions around in Framework classes.

SmtpClient client is one of the classes old enough for this. The SendFunction are the droids you are look for:

https://learn.microsoft.com/en-us/dotnet/api/system.net.mail.smtpclient.send

While the naming is a bit off and they return void, those seems to be the pre-async functions. Failure should be communicated via Exceptions in both cases.

Sign up to request clarification or add additional context in comments.

Comments

1

Given your comment that you want to have SendEmail behave like fire & forget, I would propose using

Task.Run(() => _testService.SendEmail(data));

This will give the unit of work to the threadpool and free your request from the duty of waiting for this task. Generelly this is advised for fire & forget.

As a rule of thumb otherwise, it's generally a bad idea to call asynchronous things from a synchronous context. Do async all the way, or be prepared for deadlocking. For example, you could simply make your controller actions asynchronous as well.

1 Comment

In this particular case it's OK to call some async stuff in fire-and-forget way from synchronous code.
0

If you will need use some result of sending:

    public async IHttpActionResult Post(data)
 {
     var t = Task.Run(() =>_testService.SendEmail(data));

     var result = await t;
     // do something with result
 }

- but of course your SendEmail function should return Task<> instead of Task ...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.