【问题标题】:How SendSync deals with thread poolSendSync 如何处理线程池
【发布时间】:2019-04-13 03:29:22
【问题描述】:

问题1:

我正在使用 SendAsync 发送消息:

https://docs.microsoft.com/en-us/dotnet/api/system.net.mail.smtpclient.sendasync?view=netframework-4.7.2

我正在发送大量电子邮件,并且消息回调延迟太多:client.SendCompleted

电子邮件是异步发送的,但回调似乎是串行的,似乎只有一个线程发送和接收电子邮件。

例如如果消息回调延迟 1 秒从邮件服务器返回,并且我发送 20 封电子邮件,它将延迟大约 20 秒以传递和完成所有消息。

所以看起来只有一个线程在顺序队列中发送消息...

如果 SendAsync 内部处理线程池,有没有办法改变这个池中的线程数,max num threads 以及与线程池相关的其他事情?

问题2:

关于 SendMailAsync 的另一个相关问题: https://docs.microsoft.com/en-us/dotnet/api/system.net.mail.smtpclient.sendmailasync?view=netframework-4.7.2

在内部,SendMailAsync 与 SendAsync 做同样的事情,尽管代码设计有些不同?

SendAsync 与 SendMailAsync 的真正区别是什么?它应该解决我在问题 1 中涉及的问题吗?

代码

Dim counter = 0

Public Async Function SendEmail(email As String, bodystuff As String) As Task
    Dim smtp As New SmtpClient() '"email-smtp.us-west-3.amazonaws.com")
    Dim hostloginpass = "email-smtp.us-west-3.amazonaws.com, AKDKJDAKJ2SKJMSDKJ2,AK2KD298;kdj2kjdkjaiuwkmp2KKK2098K2la97ksjNW,Test_Site"
    smtp.Host = cla_util.sGetToken(hostloginpass, 1, ",")
    smtp.Port = 587
    smtp.Credentials = New System.Net.NetworkCredential(getTokenFromArr(hostloginpass, 2, ","), getTokenFromArr(hostloginpass, 3, ","))
    smtp.EnableSsl = true

    Dim from As New MailAddress("contact@myserver.com", "Info", System.Text.Encoding.UTF8)
    Dim [to] As New MailAddress(email)
    Dim message As New MailMessage(from, [to])
    message.Body = String.Format("The message I want to send is to this <b>contact: {0}{1}</b>", vbCrLf, bodystuff)
    message.IsBodyHtml = True
    message.BodyEncoding = System.Text.Encoding.UTF8
    message.Subject = "Test email subject"
    message.SubjectEncoding = System.Text.Encoding.UTF8


    'commented -> Await smtp.SendMailAsync(message)
    smtp.SendMailAsync(message)

    counter = counter + 1

    System.Console.WriteLine("Counter -> " & counter)
End Function

Dim _isCompleted
Dim _timing

Dim Tasks As New ArrayList

Public Async Sub StartEmailRun()
    Try
        Dim sWatch As New Stopwatch()

        sWatch.Start()

        For i = 0 To 50
            Tasks.Add(SendEmail("a_test_email@gmail.com", "email test"))
        Next

        Console.WriteLine("SETP OUT OF THE SENDING")

        _isCompleted = True

        sWatch.Stop()
        _timing = sWatch.ElapsedMilliseconds

    Catch ex As Exception
        MsgBox(ex.ToString)
    End Try
End Sub

Public Async Sub StartEmailRun2()
    Try
        Dim sWatch As New Stopwatch()

        sWatch.Start()

For i = 0 To 50
    Dim thread as New Thread(
      Sub() 
        SendEmail("a_test_email@gmail.com", "email test")
      End Sub
    )
    thread.Start()
Next

        Console.WriteLine("SETP OUT OF THE SENDING")

        _isCompleted = True

        sWatch.Stop()
        _timing = sWatch.ElapsedMilliseconds

    Catch ex As Exception
        MsgBox(ex.ToString)
    End Try
End Sub

【问题讨论】:

  • 他们在后台使用相同的方法,但第二个从TaskCompletionSource返回一个任务。这是可以等待的。第一个使用SendOrPostCallback。考虑它是事件驱动的。处理这些对象池的方式不同。使用SendMailAsync 方法,您可以启动任务列表,使用SendAsync 方法您可以将处理程序附加到您的SmtpClient 对象的SendCompleted 事件。如果您不熟悉池化任务,可能会更容易使用。
  • “所以看起来只有一个线程在顺序队列中发送消息” - 该过程是异步操作,因此不涉及特定线程。也许延迟是由 UI 线程必须处理所有这些回调引起的?您是从SendComplete 回调发送消息,还是使用多个SmtpClients 并一次发送所有消息?请在您的问题中包含一些代码,以便我们了解实际情况。
  • @VisualVincent,你说没有具体的线程,但是我可以看到很多线程在发送邮件后退出。
  • @Jimi,如果 SendAsync 方法使用它们的内部线程池,什么会导致 SendCompletedCallback 延迟?我认为某处存在限制,可能内部线程池设置为只有一个线程,因此我看到了顺序行为
  • 如前所述,SendMailAsync 设置了一个TaskCompletionSource,它作为 SendAsync 方法的Object 传递。它还设置了一个自定义的SendCompleted 事件,该事件处理错误/取消状态并调用[TaskCompletionSource].TrySetResults()。它返回一个任务。您如何处理这些任务(以及您安排它们的方式)取决于您。您可以将任务作为线程池线程运行,等待单个任务或Task.WhenAll() 一个任务列表。在这种情况下,任务在哪里运行,这与您无关,也无关紧要。

标签: vb.net sendmail smtpclient


【解决方案1】:

我认为的问题是 SmtpClient 已经过时了:

https://docs.microsoft.com/pt-br/dotnet/api/system.net.mail.smtpclient?view=netframework-4.7.2

“SmtpClient 不支持许多现代协议。它仅兼容。它非常适合来自工具的一次性电子邮件,但不能扩展到协议的现代要求。”

“使用 MailKit 或其他库。”

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-03
    • 2015-03-23
    • 2021-08-28
    • 1970-01-01
    • 1970-01-01
    • 2015-02-19
    • 2018-07-19
    相关资源
    最近更新 更多