使用 System.Net.Mail 发送电子邮件 - 使用同步方法 'Send' 有效,但 'SendAsync' 无效

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

我正在尝试使用 F# 发送电子邮件,发现使用 Send 时似乎有效的代码片段。我正在使用 gmail 帐户并确保发件人帐户允许安全性较低的应用程序使用它,并且电子邮件和密码组合是正确的。我也在使用端口 587SendAsync 似乎不起作用,但它也没有抛出任何看起来很奇怪的异常。

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

我想知道我是否做错了什么。我目前正在测试项目中直接从 main 调用函数。

听起来您的程序可能在 SendAsync 完成之前退出。作为测试,尝试在 main 的末尾放置一个 Console.ReadLine 以防止过早退出。

因为 client.SendAsync(msg, msg) returns a Task 你需要等待并在同步函数中阻塞它,例如像这样:

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