System.OutOfMemoryException 使用 MailKit 下载大量附件时
System.OutOfMemoryException while downloading a lot of attachments with MailKit
我正在从几个电子邮件帐户下载附件。例如,我在每个帐户上有 300 个附件(它们是镜像)。当我只想从一个帐户下载附件时,程序日志中出现错误:
...
09.04.2017 16:10:07: Download attachment nr 108 from task Movie.avi
09.04.2017 16:10:59: Download attachment nr 109 from task Movie.avi
09.04.2017 16:11:26: Download attachment nr 110 from task Movie.avi
09.04.2017 16:12:07: Download attachment nr 111 from task Movie.avi
09.04.2017 16:12:34: Download attachment nr 112 from task Movie.avi
09.04.2017 16:13:07: Download attachment nr 113 from task Movie.avi
09.04.2017 16:13:55: Download attachment nr 114 from task Movie.avi
09.04.2017 16:14:03: System.OutOfMemoryException: Zgłoszono wyjątek typu 'System.OutOfMemoryException'.
w MimeKit.IO.MemoryBlockStream.Write(Byte[] buffer, Int32 offset, Int32 count)
w MailKit.Net.Imap.ImapFolder.FetchStream(ImapEngine engine, ImapCommand ic, Int32 index)
w MailKit.Net.Imap.ImapEngine.ProcessUntaggedResponse(CancellationToken cancellationToken)
w MailKit.Net.Imap.ImapCommand.Step()
w MailKit.Net.Imap.ImapEngine.Iterate()
w MailKit.Net.Imap.ImapEngine.Wait(ImapCommand ic)
w MailKit.Net.Imap.ImapFolder.GetMessage(UniqueId uid, CancellationToken cancellationToken, ITransferProgress progress)
w MailExchange.Form1.makeDownload(String nazwa) w c:\Users\DamianOS.MP5\Documents\mailexchange\MailExchange\Form1.cs:wiersz 1086
09.04.2017 16:14:47: System.OutOfMemoryException: Zgłoszono wyjątek typu 'System.OutOfMemoryException'.
w MailKit.Net.Imap.ImapStream.ReadQuotedStringToken(Byte* inbuf, CancellationToken cancellationToken)
w MailKit.Net.Imap.ImapStream.ReadToken(String specials, CancellationToken cancellationToken)
w MailKit.Net.Imap.ImapStream.ReadToken(CancellationToken cancellationToken)
w MailKit.Net.Imap.ImapUtils.ParseEnvelopeAddress(ImapEngine engine, String format, CancellationToken cancellationToken)
w MailKit.Net.Imap.ImapUtils.ParseEnvelopeAddressList(InternetAddressList list, ImapEngine engine, String format, CancellationToken cancellationToken)
w MailKit.Net.Imap.ImapUtils.ParseEnvelope(ImapEngine engine, CancellationToken cancellationToken)
w MailKit.Net.Imap.ImapFolder.FetchSummaryItems(ImapEngine engine, ImapCommand ic, Int32 index)
w MailKit.Net.Imap.ImapEngine.ProcessUntaggedResponse(CancellationToken cancellationToken)
w MailKit.Net.Imap.ImapCommand.Step()
w MailKit.Net.Imap.ImapEngine.Iterate()
w MailKit.Net.Imap.ImapEngine.Wait(ImapCommand ic)
w MailKit.Net.Imap.ImapFolder.Fetch(Int32 min, Int32 max, MessageSummaryItems items, CancellationToken cancellationToken)
w MailExchange.Form1.makeDownload(String nazwa) w c:\Users\DamianOS.MP5\Documents\mailexchange\MailExchange\Form1.cs:wiersz 1041
09.04.2017 16:15:04: System.OutOfMemoryException: Zgłoszono wyjątek typu 'System.OutOfMemoryException'.
w System.Text.StringBuilder..ctor(String value, Int32 startIndex, Int32 length, Int32 capacity)
w MimeKit.Utils.ParseUtils.TryParseDotAtom(Byte[] text, Int32& index, Int32 endIndex, Byte[] sentinels, Boolean throwOnError, String tokenType, String& dotatom)
w MimeKit.InternetAddress.TryParseAddrspec(Byte[] text, Int32& index, Int32 endIndex, Byte[] sentinels, Boolean throwOnError, String& addrspec)
w MimeKit.InternetAddress.TryParseMailbox(ParserOptions options, Byte[] text, Int32 startIndex, Int32& index, Int32 endIndex, String name, Int32 codepage, Boolean throwOnError, InternetAddress& address)
w MimeKit.InternetAddress.TryParse(ParserOptions options, Byte[] text, Int32& index, Int32 endIndex, AddressParserFlags flags, InternetAddress& address)
w MimeKit.InternetAddressList.TryParse(ParserOptions options, Byte[] text, Int32& index, Int32 endIndex, Boolean isGroup, Boolean throwOnError, List`1& addresses)
w MimeKit.MimeMessage.AddAddresses(Header header, InternetAddressList list)
w MimeKit.MimeMessage.HeadersChanged(Object o, HeaderListChangedEventArgs e)
w MimeKit.HeaderList.OnChanged(Header header, HeaderListChangedAction action)
w MimeKit.HeaderList.Add(Header header)
w MimeKit.MimeMessage..ctor(ParserOptions options, IEnumerable`1 headers)
w MimeKit.MimeParser.ParseMessage(Byte* inbuf)
w MimeKit.MimeParser.ParseMessage(CancellationToken cancellationToken)
w MailKit.Net.Pop3.Pop3Client.DownloadHeaderContext.Parse(Pop3Stream data, CancellationToken cancellationToken)
w MailKit.Net.Pop3.Pop3Client.DownloadContext`1.OnDataReceived(Pop3Engine pop3, Pop3Command pc, String text)
w MailKit.Net.Pop3.Pop3Engine.ReadResponse(Pop3Command pc)
w MailKit.Net.Pop3.Pop3Engine.Iterate()
w MailKit.Net.Pop3.Pop3Client.DownloadContext`1.DownloadItem(Int32 seqid, Boolean headersOnly, CancellationToken cancellationToken)
w MailKit.Net.Pop3.Pop3Client.GetMessageHeaders(Int32 index, CancellationToken cancellationToken)
w MailExchange.Form1.makeDownload(String nazwa) w c:\Users\DamianOS.MP5\Documents\mailexchange\MailExchange\Form1.cs:wiersz 1053
例如,当我从第一个帐户下载 100 个附件,从第二个帐户下载 100 个附件,从第三个帐户下载 100 个附件时,一切正常。但是我想从一个帐户下载 300 个附件。有错误的行:
//1086 line:
readyMessages.Add(client.Inbox.GetMessage(imapReadySubjects[posortowanaLista[i]].UniqueId, cancellationToken, progress));
//1041 line:
IList<IMessageSummary> allMailList = client.Inbox.Fetch(0, -1, MessageSummaryItems.Envelope | MessageSummaryItems.UniqueId, cancellationToken);
//1053 line:
for (int i = 0; i < client2.Count; i++)
allMailLists.Add(client2.GetMessageHeaders(i), i);
问题是您在 List
.
中保存了数百条消息
解决方案:不要那样做。
为什么你需要 readyMessages
列表?您只能访问列表中的最后一个元素(这是最近下载的消息)。
我正在从几个电子邮件帐户下载附件。例如,我在每个帐户上有 300 个附件(它们是镜像)。当我只想从一个帐户下载附件时,程序日志中出现错误:
...
09.04.2017 16:10:07: Download attachment nr 108 from task Movie.avi
09.04.2017 16:10:59: Download attachment nr 109 from task Movie.avi
09.04.2017 16:11:26: Download attachment nr 110 from task Movie.avi
09.04.2017 16:12:07: Download attachment nr 111 from task Movie.avi
09.04.2017 16:12:34: Download attachment nr 112 from task Movie.avi
09.04.2017 16:13:07: Download attachment nr 113 from task Movie.avi
09.04.2017 16:13:55: Download attachment nr 114 from task Movie.avi
09.04.2017 16:14:03: System.OutOfMemoryException: Zgłoszono wyjątek typu 'System.OutOfMemoryException'.
w MimeKit.IO.MemoryBlockStream.Write(Byte[] buffer, Int32 offset, Int32 count)
w MailKit.Net.Imap.ImapFolder.FetchStream(ImapEngine engine, ImapCommand ic, Int32 index)
w MailKit.Net.Imap.ImapEngine.ProcessUntaggedResponse(CancellationToken cancellationToken)
w MailKit.Net.Imap.ImapCommand.Step()
w MailKit.Net.Imap.ImapEngine.Iterate()
w MailKit.Net.Imap.ImapEngine.Wait(ImapCommand ic)
w MailKit.Net.Imap.ImapFolder.GetMessage(UniqueId uid, CancellationToken cancellationToken, ITransferProgress progress)
w MailExchange.Form1.makeDownload(String nazwa) w c:\Users\DamianOS.MP5\Documents\mailexchange\MailExchange\Form1.cs:wiersz 1086
09.04.2017 16:14:47: System.OutOfMemoryException: Zgłoszono wyjątek typu 'System.OutOfMemoryException'.
w MailKit.Net.Imap.ImapStream.ReadQuotedStringToken(Byte* inbuf, CancellationToken cancellationToken)
w MailKit.Net.Imap.ImapStream.ReadToken(String specials, CancellationToken cancellationToken)
w MailKit.Net.Imap.ImapStream.ReadToken(CancellationToken cancellationToken)
w MailKit.Net.Imap.ImapUtils.ParseEnvelopeAddress(ImapEngine engine, String format, CancellationToken cancellationToken)
w MailKit.Net.Imap.ImapUtils.ParseEnvelopeAddressList(InternetAddressList list, ImapEngine engine, String format, CancellationToken cancellationToken)
w MailKit.Net.Imap.ImapUtils.ParseEnvelope(ImapEngine engine, CancellationToken cancellationToken)
w MailKit.Net.Imap.ImapFolder.FetchSummaryItems(ImapEngine engine, ImapCommand ic, Int32 index)
w MailKit.Net.Imap.ImapEngine.ProcessUntaggedResponse(CancellationToken cancellationToken)
w MailKit.Net.Imap.ImapCommand.Step()
w MailKit.Net.Imap.ImapEngine.Iterate()
w MailKit.Net.Imap.ImapEngine.Wait(ImapCommand ic)
w MailKit.Net.Imap.ImapFolder.Fetch(Int32 min, Int32 max, MessageSummaryItems items, CancellationToken cancellationToken)
w MailExchange.Form1.makeDownload(String nazwa) w c:\Users\DamianOS.MP5\Documents\mailexchange\MailExchange\Form1.cs:wiersz 1041
09.04.2017 16:15:04: System.OutOfMemoryException: Zgłoszono wyjątek typu 'System.OutOfMemoryException'.
w System.Text.StringBuilder..ctor(String value, Int32 startIndex, Int32 length, Int32 capacity)
w MimeKit.Utils.ParseUtils.TryParseDotAtom(Byte[] text, Int32& index, Int32 endIndex, Byte[] sentinels, Boolean throwOnError, String tokenType, String& dotatom)
w MimeKit.InternetAddress.TryParseAddrspec(Byte[] text, Int32& index, Int32 endIndex, Byte[] sentinels, Boolean throwOnError, String& addrspec)
w MimeKit.InternetAddress.TryParseMailbox(ParserOptions options, Byte[] text, Int32 startIndex, Int32& index, Int32 endIndex, String name, Int32 codepage, Boolean throwOnError, InternetAddress& address)
w MimeKit.InternetAddress.TryParse(ParserOptions options, Byte[] text, Int32& index, Int32 endIndex, AddressParserFlags flags, InternetAddress& address)
w MimeKit.InternetAddressList.TryParse(ParserOptions options, Byte[] text, Int32& index, Int32 endIndex, Boolean isGroup, Boolean throwOnError, List`1& addresses)
w MimeKit.MimeMessage.AddAddresses(Header header, InternetAddressList list)
w MimeKit.MimeMessage.HeadersChanged(Object o, HeaderListChangedEventArgs e)
w MimeKit.HeaderList.OnChanged(Header header, HeaderListChangedAction action)
w MimeKit.HeaderList.Add(Header header)
w MimeKit.MimeMessage..ctor(ParserOptions options, IEnumerable`1 headers)
w MimeKit.MimeParser.ParseMessage(Byte* inbuf)
w MimeKit.MimeParser.ParseMessage(CancellationToken cancellationToken)
w MailKit.Net.Pop3.Pop3Client.DownloadHeaderContext.Parse(Pop3Stream data, CancellationToken cancellationToken)
w MailKit.Net.Pop3.Pop3Client.DownloadContext`1.OnDataReceived(Pop3Engine pop3, Pop3Command pc, String text)
w MailKit.Net.Pop3.Pop3Engine.ReadResponse(Pop3Command pc)
w MailKit.Net.Pop3.Pop3Engine.Iterate()
w MailKit.Net.Pop3.Pop3Client.DownloadContext`1.DownloadItem(Int32 seqid, Boolean headersOnly, CancellationToken cancellationToken)
w MailKit.Net.Pop3.Pop3Client.GetMessageHeaders(Int32 index, CancellationToken cancellationToken)
w MailExchange.Form1.makeDownload(String nazwa) w c:\Users\DamianOS.MP5\Documents\mailexchange\MailExchange\Form1.cs:wiersz 1053
例如,当我从第一个帐户下载 100 个附件,从第二个帐户下载 100 个附件,从第三个帐户下载 100 个附件时,一切正常。但是我想从一个帐户下载 300 个附件。有错误的行:
//1086 line:
readyMessages.Add(client.Inbox.GetMessage(imapReadySubjects[posortowanaLista[i]].UniqueId, cancellationToken, progress));
//1041 line:
IList<IMessageSummary> allMailList = client.Inbox.Fetch(0, -1, MessageSummaryItems.Envelope | MessageSummaryItems.UniqueId, cancellationToken);
//1053 line:
for (int i = 0; i < client2.Count; i++)
allMailLists.Add(client2.GetMessageHeaders(i), i);
问题是您在 List
.
解决方案:不要那样做。
为什么你需要 readyMessages
列表?您只能访问列表中的最后一个元素(这是最近下载的消息)。