dnorbert
dnorbert

Reputation: 23

Using System.Net.Mail to send emails - using the synchronous method 'Send' works, but 'SendAsync' does not

I'm trying to send emails using F#, and found a code snippet that seems to work when using Send. I'm using gmail accounts and made sure that the sender account enables less secure apps to use it and that the email & password combo is correct. I'm also using port 587. SendAsync does not seem to work, but it's also not throwing any exceptions which seems strange.

let sendMailMessage email topic msg =
    let msg = new MailMessage(sender, email, topic, msg)
    msg.IsBodyHtml <- false

    let client = new SmtpClient(server, port)
    client.EnableSsl <- true
    client.UseDefaultCredentials <- false
    client.Credentials <- System.Net.NetworkCredential(sender, password)

    client.SendCompleted |> Observable.add(fun e ->
        let msg = e.UserState :?> MailMessage
        if e.Cancelled then
            ("Mail message cancelled:\r\n" + msg.Subject) |> Console.WriteLine
        if e.Error <> null then
            ("Sending mail failed for message:\r\n" + msg.Subject + ", reason:\r\n" + e.Error.ToString()) |> Console.WriteLine
        if msg <> Unchecked.defaultof<MailMessage> then
            msg.Dispose()
        if client<>Unchecked.defaultof<SmtpClient> then
            client.Dispose()
    )

    try
        client.SendAsync(msg, msg) // runs fine but doesn't actually send an email
        client.Send(msg) // this works, but it's also blocking
    with
    | e -> printfn "%A" e

I'm wondering if I'm doing anything wrong. I'm currently straight up calling the function from main in a test project.

Upvotes: 2

Views: 329

Answers (2)

Andreas &#197;gren
Andreas &#197;gren

Reputation: 3929

Since client.SendAsync(msg, msg) returns a Task you need to await and block on that when you're in a synchronous function, e.g. like this:

client.SendAsync(msg, msg)
|> Async.AwaitTask // Converts Task<> to Async<>
|> Async.RunSynchronously // Blocks until the async work is done.

Upvotes: 2

Brian Berns
Brian Berns

Reputation: 17143

It sounds like your program is probably exiting before SendAsync finishes. Just as a test, try putting a Console.ReadLine at the end of main to prevent premature exit.

Upvotes: 2

Related Questions