Вот функция:
Private Sub LoadEmail()
Dim loSession As RDOSession = Nothing
Dim loMessages As RDOItems = Nothing
Try
moNDRs = New List(Of NonDeliveryRecord)
loSession = New Redemption.RDOSession
loSession.LogonExchangeMailbox(MailAccountName, MailServerName)
loMessages = loSession.GetDefaultFolder(rdoDefaultFolders.olFolderInbox).Items
Dim Counter = 0
For Each loMessage As RDOMail In loMessages
Counter += 1
moNDRs.Add(CreateNDRRecord(loMessage))
Marshal.ReleaseComObject(loMessage)
loMessage = Nothing
If Counter Mod 100 = 0 Then GC.Collect()
Next
Finally
If loSession IsNot Nothing Then
loSession.Logoff()
Marshal.FinalReleaseComObject(loSession)
loSession = Nothing
End If
If loMessages IsNot Nothing Then
Marshal.FinalReleaseComObject(loMessages)
loMessages = Nothing
End If
End Try
End Sub
Используемые выше классы сообщений: Искупление . Если вы посмотрите на функцию выше, вы увидите:
If Counter Mod 100 = 0 Then GC.Collect()
Что я и должен был сделать, чтобы решить нашу проблему. Этим утром я играл с профилировщиками памяти (муравьи и точка), чтобы посмотреть, смогу ли я что-нибудь выяснить, но пока все выглядит хорошо. Я не на низком уровне, не знаю, кто знает все тонкости WindGB.
Я получаю ошибку:
Ошибка в IMAPISession :: OpenEntry: MAPI_E_TOO_BIG
Строка, где я всегда получаю ошибку, прокомментирована в коде ниже. Я всегда получаю ошибку после ~ 450 итераций.
Это один из немногих случаев, когда вам нужно использовать gc.collect, когда вы имеете дело с COM-объектами?
Вот функция CreateNDR со строкой, в которой происходит ошибка:
Public Function CreateNDRRecord(ByVal voMessage As RDOMail) As NonDeliveryRecord
Dim loItem As RDOReportItem = Nothing
Dim loMatches As MatchCollection = Nothing
Dim loNonDeliveryCode As NonDeliveryRecord = New NonDeliveryRecord
Dim lsMessage As String = String.Empty
Try
loNonDeliveryCode.IsBadMessage = False
loNonDeliveryCode.MailMessageId = voMessage.EntryID
'Debug.Print(voMessage.MessageClass.Equals("REPORT.IPM.Note.NDR").ToString())
If voMessage.MessageClass.Equals("REPORT.IPM.Note.NDR") Then 'error always happens here
loItem = CType(voMessage, RDOReportItem)
If voMessage.Recipients.Count <> 0 Then
loNonDeliveryCode.EmailAddress = voMessage.Recipients(1).Name
End If
loNonDeliveryCode.IsUndeliverable = True
lsMessage = loItem.ReportText
ElseIf voMessage.Subject.Contains(mconSeparator) Then
loNonDeliveryCode.EmailAddress = voMessage.Subject.Substring(voMessage.Subject.LastIndexOf(mconSeparator) + mconSeparator.Length)
loNonDeliveryCode.ErrorCode = String.Empty
loNonDeliveryCode.IsUndeliverable = True
lsMessage = voMessage.Body
End If
If loNonDeliveryCode.IsUndeliverable Then
loMatches = GetErrorType(lsMessage)
If loMatches.Count > 0 Then
loNonDeliveryCode.ErrorCode = loMatches(loMatches.Count - 1).Value
End If
Dim loNDRId = GetErrorCode(loNonDeliveryCode.ErrorCode)
If loNDRId.Count > 0 Then
loNonDeliveryCode.ErrorCodeId = CType(CType(loNDRId(0), DataRow).Item("NonDeliveryCodeId"), Integer)
loNonDeliveryCode.ErrorDescription = CType(CType(loNDRId(0), DataRow).Item("Description"), String)
loNonDeliveryCode.MarkAsInvalid = CType(CType(loNDRId(0), DataRow).Item("MarkAsInvalid"), Boolean)
Else
If voMessage.MessageClass.Equals("REPORT.IPM.Note.NDR") Then
loNonDeliveryCode.ErrorCode = String.Empty
loNDRId = GetErrorCode(loNonDeliveryCode.ErrorCode)
loNonDeliveryCode.ErrorCodeId = CType(CType(loNDRId(0), DataRow).Item("NonDeliveryCodeId"), Integer)
loNonDeliveryCode.ErrorDescription = CType(CType(loNDRId(0), DataRow).Item("Description"), String)
loNonDeliveryCode.MarkAsInvalid = CType(CType(loNDRId(0), DataRow).Item("MarkAsInvalid"), Boolean)
Else
loNonDeliveryCode.ErrorCode = String.Empty
loNonDeliveryCode.ErrorCodeId = 1
End If
End If
End If
Return loNonDeliveryCode
Catch Ex As Exception
loNonDeliveryCode.IsUndeliverable = False
loNonDeliveryCode.IsBadMessage = True
Return loNonDeliveryCode
Finally
If loItem IsNot Nothing Then
Marshal.FinalReleaseComObject(loItem)
loItem = Nothing
End If
If voMessage IsNot Nothing Then Marshal.ReleaseComObject(voMessage)
If loMatches IsNot Nothing Then
loMatches = Nothing
End If
End Try