Unexpected behavior while fetching data for a BusinessListBase class

Unexpected behavior while fetching data for a BusinessListBase class

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


kristof posted on Wednesday, June 15, 2011

Hi,

I am trying to familiarize myself with CSLA and am trying to implement an event, triggered from within the fetch of a BusinessListBase class.
I was unable to get it to work, so tried to isolate the problem by creating a simple test program:.


BaseObject is an empty class of type BusinessBase<BaseObject>.


    public class ObjectListWithEvent : BusinessListBase<ObjectListWithEvent, BaseObject>
    {
        public event EventHandler ItemAdded;
        public event EventHandler DataFetched;

        public static ObjectListWithEvent GetList()
        {
            UtilityObjects.CSLA.Criteria crit = new UtilityObjects.CSLA.Criteria();

            return DataPortal.Fetch<ObjectListWithEvent>(crit);
        }

        public void Fetch()
        {
            UtilityObjects.CSLA.Criteria crit = new UtilityObjects.CSLA.Criteria();

            DataPortal.Fetch<ObjectListWithEvent>(crit);
        }

        protected void DataPortal_Fetch(UtilityObjects.CSLA.Criteria criteria)
        {
            this.Clear();

            for (int i = 1; i <= 10; i++)
            {
                this.Add(new BaseObject());

                if (ItemAdded != null)
                    ItemAdded(this, EventArgs.Empty);
            }

            if (DataFetched != null)
            {
                DataFetched(this, EventArgs.Empty);
            }
        }
    }


Using this I get some 'unexpected behavior'. I tried to fetch the data using a constructor (so I can attach the eventhandlers) and try the typical factory method:

            private BI.Lists.ObjectListWithEvent _list = null;

            _list = new CLSASandbox.BI.Lists.ObjectListWithEvent();

            _list.ItemAdded += new EventHandler(_list_ItemAdded);
            _list.DataFetched += new EventHandler(_list_DataFetched);

            _list.Fetch();

            _list = BI.Lists.ObjectListWithEvent.GetList();



What I get is that if you debug through the code, everything seems to work as it's expected, except for the actual result:


_list.Fetch();

    DataPortal_Fetch is loaded correctly, containing the expected 10 items, but the actual _list member still contains 0.


_list = BI.Lists.ObjectListWithEvent.GetList();


    DataPortal_Fetch is loaded correctly, containing the expected 10 items, as does the _list member. But, I can't attach the eventhandlers to this.



What do I need to do to be able to get the events I want working properly (eg for use with a progressbar)?

Thanks

Kristof

JonnyBee replied on Wednesday, June 15, 2011

Hi,

I'd rather us an animated gif than relying on events in a BO.

A: Your data access would probably go on a background thread and run asyncronously
B: You may have multiple async operations going at the same time.
C: Will only work with local dataportal (not with any remote dataportal out of the box)
D: Events in aBO must be marked as [NonSerialized, NotUndoable]. They cannot be part of BeginEdit snapshot (for editable objects) or be serialized across the wire.

If you are absolutely sure to do this on a local portal imlementation - I'd rather set a StatusObject into ApplicationContext.LocalContext and have the BO call events on the StatusObject. And the StatusObject must make sure to only raise the event on the UI Thread so it will work on an async BO.

Remember, in order to keep your UI responsive (and even update the progressbar, ie repaint itself) you MUST run your data access asyncronously.

RockfordLhotka replied on Wednesday, June 15, 2011

Another possible solution is to use the technique shown in the Samples\Silverlight\cs\PagedList sample.

This loads the list by using a series of data portal requests - each request loading a "page" of data. It would be relatively easy to implement progress in this scenario, because the client could raise an event or update a counter as it receives each page.

No need for all the complexity of getting events back from the app server to the client - just get chunks of data back, and report on each chunk.

Copyright (c) Marimer LLC