32k limit when adding small contact items using RDOFolder.Items.Add

C

Chris

Hi,

I'm using Redemption's new RDO objects (4.0, very nice) and am having a
problem iterating through an sql table of contacts and converting them
into Exchange contacts. I am using RDOFolder.Items.Add and after
calling this about 260 times RDOFolder.Items.Add returns nothing. If I
keep a running total of the size of the contact items added the problem
occurs exactly when 32k of of total contacts have been added. I
imagine that a MAPITable is being used underneath but I don't know how
to reset or flush it in order to process more contacts. I've tried a
few things which you can see in the code below.

Cheers,
Chris

Here is the code snippet (vb.net):


For Each dr As DataRow In dt.Rows
With New MapiCodes
c = contactsFolder.Items.Add("IPM.Contact")
If c Is Nothing Then
MsgBox("c is nothing") ' This happens when
bufferSize reached 32000
End If

c.Fields(.CdoPR_TITLE) = dr("Title").ToString
c.Fields(.CdoPR_GIVEN_NAME) = dr("FirstName").ToString
c.Fields(.CdoPR_SURNAME) = dr("FamilyName").ToString
c.Fields(.CdoContact_EmailEmailAddress) =
dr("Email").ToString
c.Fields(.CdoPR_DISPLAY_NAME) =
dr("CalcFullNameInv").ToString
c.Fields(.CdoContact_FileUnder) = .CdoPR_DISPLAY_NAME
c.Fields(.CdoPR_COMPANY_NAME) =
dr("Institution").ToString
c.Fields(.CdoPR_BUSINESS_TELEPHONE_NUMBER) =
dr("Tel1").ToString
' c.Fields("urn:schemas:contacts:fileasid") = 32791
' c.Fields(.cdocontact
' .Add(CdoContact_FileUnderID, &HFFFFFFFF,
CdoPropSetID3)
c.Save()

bufferSize += c.Size
totalSize += c.Size
Debug.WriteLine(c.Size & "/" & bufferSize & "/" &
totalSize)
If bufferSize > 31000 Then
Debug.WriteLine("Now trying to reset")
' mapiUtils.Cleanup() ' Doesn't reset
contactsFolder = Nothing ' Doesn't reset
contactsFolder = GetFolderMapi(path,
publicRootFolder) ' Doesn't reset
bufferSize = 0
End If
End With
Next
mapiUtils.Cleanup()
 
D

Dmitry Streblechenko

Most likely you are running into the 255 RPC channels/process limit - each
Exchange object has an open RPC channel. Try to set each object to Nothing
as soon as you are done with it. Are you using VB 6 or VB.Net?

Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
 
C

Chris

Hi Dmitry. I'm using vb.net in this case. I counted the number of
objects created before failing and it does correspond to 255. Here is
my new code where I try to set the newly created contact object c to
nothing and then output various statistics:

For Each dr As DataRow In dt.Rows
With New MapiCodes
c = contactsFolder.Items.Add("IPM.Contact")
If c Is Nothing Then
' MsgBox("c is nothing")
End If

c.Fields(.CdoPR_DISPLAY_NAME_PREFIX) =
dr("Title").ToString
c.Fields(.CdoPR_TITLE) = dr("Function").ToString
c.Fields(.CdoPR_GIVEN_NAME) = dr("FirstName").ToString
c.Fields(.CdoPR_SURNAME) = dr("FamilyName").ToString
c.Fields(.CdoContact_EmailEmailAddress) =
dr("Email").ToString
c.Fields(.CdoPR_DISPLAY_NAME) =
dr("CalcFullNameInv").ToString
c.Fields(.CdoPR_COMPANY_NAME) =
dr("Institution").ToString
c.Fields(.CdoPR_BUSINESS_TELEPHONE_NUMBER) =
dr("Tel1").ToString

c.Save()

bufferSize += c.Size
totalSize += c.Size
cObjects += 1
Debug.WriteLine(cObjects & " " & c.Size & "/" &
bufferSize & "/" & totalSize)

c = Nothing
End With
Next

Here is the output:

countOfObject size of contact/buffer size/total size.
..
..
..
245 134/32830/32830
246 134/32964/32964
247 134/33098/33098
248 134/33232/33232
249 134/33366/33366
250 134/33500/33500
An unhandled exception of type 'System.NullReferenceException' occurred
in redempTest.exe
Additional information: Object reference not set to an instance of an
object.
The program '[3388] redempTest.exe' has exited with code 0 (0x0).

So it's failing after 250 contact objects. Add in the session, store,
public folder and contacts folder objects I also created and that
brings us pretty close to 255 - so your suggestion seems right on the
money.

Question is then, how do I release this objects in vb 6.0 and vb.net?
Setting c to nothing doesn't seem to work here (maybe this works in vb
6.0 but not with dotnet garbage collection ....).

Cheers,
Chris
 
C

Chris

Answered my own question. In dotnet garbage collecting it does the
trick. In vb 6.0 I don't know .... Thanks Dmitry for solving this.
Here is the final working code:

' Each Exchange object creates an RPC channel and the Exchange
server
' limits the number of channels to 255. So when creating a
large number
' of mapi objects we need to force periodic garbage collection
so that this
' limit is not exceeded. If the limit is reached, new objects
can not
' be created.

Dim c As RDOMail
Dim cObjects As Integer
Const MaxObjects = 240 ' Allow for a few other objects.

GC.Collect() ' Start off clean
cObjects = 0
Try
For Each dr As DataRow In dt.Rows
With New MapiCodes
If cObjects > MaxObjects Then
Debug.WriteLine("Garbage collection")
GC.Collect() : cObjects = 0
End If

c = contactsFolder.Items.Add("IPM.Contact")
If c Is Nothing Then
' Try garbage collecting in case MaxObjects
underestimated
' the number of objects.
GC.Collect() : cObjects = 0
c = contactsFolder.Items.Add("IPM.Contact")
If c Is Nothing Then Throw New Exception("Error
creating RDOMail contact item.")
End If

c.Fields(.CdoPR_DISPLAY_NAME_PREFIX) =
dr("Title").ToString
c.Fields(.CdoPR_TITLE) = dr("Function").ToString
c.Fields(.CdoPR_GIVEN_NAME) =
dr("FirstName").ToString
c.Fields(.CdoPR_SURNAME) =
dr("FamilyName").ToString
c.Fields(.CdoContact_EmailEmailAddress) =
dr("Email").ToString
c.Fields(.CdoPR_DISPLAY_NAME) =
dr("CalcFullNameInv").ToString
c.Fields(.CdoPR_COMPANY_NAME) =
dr("Institution").ToString
c.Fields(.CdoPR_BUSINESS_TELEPHONE_NUMBER) =
dr("Tel1").ToString

c.Save()

cObjects += 1
Debug.WriteLine(cObjects)
End With
Next
Catch ex As Exception
MsgBox(ex.ToString) ' TODO log this
Finally
session.Logoff()
mapiUtils.Cleanup()
End Try
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top