Skip to content

Instantly share code, notes, and snippets.

@Nilzor
Created November 5, 2011 11:30
Show Gist options
  • Save Nilzor/1341410 to your computer and use it in GitHub Desktop.
Save Nilzor/1341410 to your computer and use it in GitHub Desktop.
A CSLA list that loads in the background giving the consumer an option to specifiy a load indicator object
using System;
using System.ComponentModel;
using Csla;
using Csla.Core;
using ErrorEventArgs = Csla.Core.ErrorEventArgs;
namespace Business.Entities
{
public delegate void ExceptionEventHandler(object sender, ErrorEventArgs args);
public abstract class BackgroundLoadingList<T,C> : BusinessListBase<T, C>
where T : BusinessListBase<T,C> where C: IEditableBusinessObject/*, INamable*/
{
/// <summary>
/// Triggers when an exception occures when loading on the same thread as the original invoke
/// </summary>
public event ExceptionEventHandler LoadErrorOccured;
private Func<BusinessListBase<T, C>> _loadFunction;
private C _loadIndicator;
public void LoadAsync(Func<BusinessListBase<T, C>> loadFunction)
{
LoadAsyncUsingBackgroundWorker(loadFunction);
}
public void LoadAsync(Func<BusinessListBase<T, C>> loadFunction, C loadIndicatorObject)
{
Add(loadIndicatorObject);
LoadAsyncUsingBackgroundWorker(loadFunction);
}
public void LoadAsyncUsingBeginInvoke(Func<BusinessListBase<T, C>> loadFunction)
{
_loadFunction = loadFunction;
loadFunction.BeginInvoke(LoadComplete, null);
}
internal void LoadComplete(IAsyncResult result)
{
// This ends up on a different thread than BeginInvoke was called on. = trouble
var res = _loadFunction.EndInvoke(result);
RaiseListChangedEvents = false;
foreach (var elem in res) Add(elem);
RaiseListChangedEvents = true;
//ResetBindings();
_loadFunction = null;
}
private void LoadAsyncUsingBackgroundWorker(Func<BusinessListBase<T, C>> loadFunction)
{
_loadFunction = loadFunction;
var worker = new BackgroundWorker();
worker.DoWork += (sender, e) => e.Result = loadFunction();
worker.RunWorkerCompleted += Load_RunWorkerCompleted;
worker.RunWorkerAsync();
}
internal void Load_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs args)
{
if (args.Error == null)
{
var res = (BusinessListBase<T, C>)args.Result;
RaiseListChangedEvents = false;
Clear();
foreach (var elem in res) Add(elem);
RaiseListChangedEvents = true;
ResetBindings();
}
else
{
if (LoadErrorOccured != null) LoadErrorOccured.Invoke(this, new ErrorEventArgs(sender, args.Error));
}
_loadFunction = null;
}
}
public interface INamable
{
void SetName(string name);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment