调用AuthenticateAsync失败后MailKit日志为空的原因
协议日志为空的原因及修复方案
核心问题分析
- 流指针位置错误:
ProtocolLogger写入日志后,MemoryStream的当前读取指针(Position)停留在日志内容的末尾,直接调用reader.ReadToEnd()时,从末尾开始读取自然获取不到内容。 - 未刷新日志缓冲区:
ProtocolLogger自身带有缓冲区,认证失败抛出异常时,缓冲区中的日志可能还未写入MemoryStream,仅调用stream.Flush()无法触发日志缓冲区的刷新。 - StreamReader创建时机不当:提前创建
StreamReader会占用流资源,且后续读取时的指针问题会被放大。
修复后的代码示例
public async Task SendMailMessage(M.MailMessage message) { using MemoryStream stream = new MemoryStream(10_240); using ProtocolLogger logger = new ProtocolLogger(stream); using SmtpClient smtp = new SmtpClient(logger); try { await smtp.ConnectAsync( _config.HostName, _config.Port, _config.SecurityType == EMailSecurityType.StartTls ? SecureSocketOptions.StartTlsWhenAvailable : SecureSocketOptions.Auto ); await smtp.AuthenticateAsync(_config.UserName, _config.Password); await smtp.SendAsync(new MimeMessage(message)); await smtp.DisconnectAsync(true); } catch { // 刷新ProtocolLogger缓冲区,确保日志写入MemoryStream logger.Dispose(); // 重置流指针到起始位置 stream.Position = 0; // 读取时再创建StreamReader using StreamReader reader = new StreamReader(stream); Debug.Print(reader.ReadToEnd()); } }
关键修复点说明
- 延迟创建StreamReader:等到需要读取日志时再实例化
StreamReader,避免提前占用流资源。 - 强制刷新日志缓冲区:调用
logger.Dispose()触发缓冲区内容写入(ProtocolLogger实现了IDisposable,Dispose时会自动刷新)。 - 重置流指针位置:将
stream.Position设置为0,让StreamReader从流的起始位置读取完整日志。
内容的提问来源于stack exchange,提问作者AxD
相关产品推荐
相关产品推荐

