You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Microsoft Graph Client发送邮件的控制台应用故障排查求助

问题分析与解决方案

你遇到的核心问题是控制台应用中使用Async Sub导致异步操作未完成程序就提前退出。控制台的主线程不会等待Async Sub内的异步代码执行完毕,当代码执行到Await graphEmail.SendEmail(mailInfo)时会立即返回给调用者,主线程后续直接终止程序,导致邮件发送逻辑没跑完,也看不到后续调试输出和错误信息。

具体修复步骤

1. 将Async Sub改为Async Function并返回Task

Async Sub仅适用于UI事件处理场景,控制台应用必须用Async Function让调用者能等待异步操作完成:

Private Async Function SendMailAsync(ByVal sSubject As String, ByVal sTextBody As String) As Task
    Console.WriteLine("start to SendMail")
    Dim tenant As String = Configuration.ConfigurationManager.AppSettings("tenantID")
    Dim appID As String = Configuration.ConfigurationManager.AppSettings("appID")
    Dim secret As String = Configuration.ConfigurationManager.AppSettings("secretID")
    Dim graphEmail As MyEmail.GraphEmail = New MyEmail.GraphEmail(tenant, appID, secret)
    Try
        Dim body As String = "START TIME: " & startTime.ToString & Environment.NewLine
        body &= "END TIME: " & endTime.ToString & Environment.NewLine & Environment.NewLine
        
        Dim mailInfo As MyEmail.MailInfo= New MyEmail.MailInfo()
        mailInfo.To = Configuration.ConfigurationManager.AppSettings("TO")
        mailInfo.From = Configuration.ConfigurationManager.AppSettings("FROM")
        mailInfo.Subject = sSubject
        mailInfo.Body = body
        Dim result As String = Await graphEmail.SendEmail(mailInfo)
        Console.WriteLine(result)
        Console.ReadLine()
    Catch ex As Exception
        Console.WriteLine(ex.Message & vbCrLf & ex.StackTrace.ToString)
        Console.ReadLine()
    End Try
    Console.WriteLine("finished")
End Function

2. 在程序入口点等待异步方法完成

根据你使用的.NET版本调整入口逻辑:

  • 若为.NET Framework 4.5+:
Sub Main()
    ' 阻塞主线程等待异步方法完成
    SendMailAsync("测试主题", "测试内容").GetAwaiter().GetResult()
End Sub
  • 若为.NET Core/.NET 5+,可直接使用异步入口:
Async Function Main() As Task
    Await SendMailAsync("测试主题", "测试内容")
End Function

3. 检查GraphEmail.SendEmail的实现

确保该方法是正确的异步实现,避免使用.Wait()或.Result()这类同步阻塞调用,否则会引发死锁或异步逻辑失效。示例正确实现:

Public Async Function SendEmail(mailInfo As MailInfo) As Task(Of String)
    ' 初始化Graph客户端(使用ClientCredentialProvider)
    Dim credential = New ClientCredentialProvider(New ClientCredential(appID, secret))
    Dim client = New GraphServiceClient(credential)
    
    ' 构建邮件消息
    Dim message = New Message() With {
        .Subject = mailInfo.Subject,
        .Body = New ItemBody() With {
            .ContentType = BodyType.Text,
            .Content = mailInfo.Body
        },
        .ToRecipients = {
            New Recipient() With {
                .EmailAddress = New EmailAddress() With {.Address = mailInfo.To}
            }
        }
    }
    
    ' 异步发送邮件
    Await client.Users(mailInfo.From).SendMail(message, saveToSentItems:=True).Request().PostAsync()
    Return "邮件发送成功"
End Function

额外调试建议

  • 确认app.config中所有配置项(tenantID、appID、secretID、TO、FROM)准确无误,FROM邮箱必须是租户内有权限的账号,且Azure AD应用已添加Mail.Send应用权限并完成管理员同意。
  • 在graphEmail.SendEmail内部添加日志输出,确认Graph API是否被成功调用。
  • 查看Azure AD应用的审计日志,排查是否有API调用失败记录。

内容的提问来源于stack exchange,提问作者Y Chan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 01:43:35