How to Refresh a shared list

How to Refresh a shared list

Old forum URL: forums.lhotka.net/forums/t/812.aspx


David posted on Thursday, August 03, 2006

I have a Read Only List object that is used by multiple objects in my application. I want all objects to use the one instance of the list so I use the following shared function to access it:

Private Shared mList As ReferenceList
Public Shared Function GetList() As ReferenceList
  If mList Is Nothing Then
    mList = DataPortal.Fetch(Of ReferenceList)(New Criteria())
  End If
  Return mList
End Function

Basic stuff, and this works fine. However, I want to add a Refresh method to my list object that will cause the list to be refetched from the database. When this method is called, ALL the objects referencing the shared list need to see that it has been updated.

I tried this:

Public Sub Refresh()
  Dim NewList As ReferenceList
  mList = Nothing
  NewList = ReferenceList.GetList()
End Sub

This does cause the list to be refetched from the database, but I now have two instances of my list in memory with all the existing objects continuing to reference the old instance.

Is there some obvious way to do this, or do I have to resort to manually reconstructing the existing list object?

xal replied on Thursday, August 03, 2006

I would do this in your list:

Private mInstance as ReferenceList
Public Shared ReadOnly Property List () As ReferenceList
Get
    If mInstance Is Nothing Then
       mInstance = GetList()
    End If
    return mInstance
End Get
End Property

Public Shared Sub Invalidate()
    mInstance = Nothing
End Sub



So instead of storing the list in a field in your bo, you always call that property and you always get the better version. You also don't keep old references around...

Andrés

David replied on Thursday, August 03, 2006

Thanks for the quick reply.

mInstance would need to be declared 'Shared', but I still don't think this would solve the problem.

My understanding is that because the data portal returns a new object, you need to somehow get all existing references to point to the new object. Accessing the list through a property doesn’t really change this, unless the existing objects periodically update their reference by calling this property.

I tried clearing all the items from my old list and then adding all the items from the new list as follows:

  Public Sub Refresh
    Dim OldList As ReferenceList = Me
    mList = Nothing
    Dim NewList As ReferenceList = GetList()
    OldList.IsReadOnly = False
    For Each r As ReferenceListInfo In NewList
      OldList.Add(r)
    Next
    OldList.IsReadOnly = True
  End Sub

This worked and all the visible grids refreshed themselves, but it seems a bit of an arduous approach.

xal replied on Friday, August 04, 2006

Sorry about that... I didn't compile the sample. Damn forum ;)

I was thinking of BOs referencing the property, not grids, so I see your point.
Another possible approach would be to have a shared event in your list that you would have to listen wherever you use your list. When you catch the event, you would then update your references.

Anyway, I don't think that what you're currently doing is wrong anyway, but you'll have different references that way, which in most cases is ok, but remember that if you reference 2 different objects (or more if this is done with frequence), you're going to be allocating more and more memory and the GC will not get rid of those...
Which in your case is probably not that big of a problem since the items in all list will be the same, so only the list object will be different which isn't a memory waster.
Keep in mind though that lists usually call SetParent in the children, I don't know if and how that could affect you in any way. I believe this is not the case for name value lists, but I'm not 100% sure.


Andrés

Copyright (c) Marimer LLC