Passing collection to BackgroundWorker for processing

Posts   
 
    
JimHugh
User
Posts: 191
Joined: 16-Nov-2005
# Posted on: 08-Aug-2006 20:02:14   

Please excuse me if I'm asking this in the wrong place. I'm trying to figure out the best way to pass a collection to a background thread for processing.

I've setup a WinForms BackGroundWorker component (using the basic plumbing from MSDN.

Reading from the collection is not a problem, but setting a property (i.e. the ModifiedDate property below) on an entity contained in the collection gives me a cross thread execution error when run from a background thread.

I've read about using InvokeRequired and Invoke, but don't know where this would apply here.

The entitycollection is set as the datasource of a BindingSource on the form, if I disconnect it durng processing, would that fix it?

Open to any ideas or pointers.

VS2005, LLBLGen 2.0, Adapter


// designer code
this.bgParse.DoWork += new 
System.ComponentModel.DoWorkEventHandler(this.bgParse_DoWork);

// form code
EntityCollection<MyEntity> ec = 
new EntityCollection<MyEntity>(new MyEntityFactory());

private void bgParse_DoWork(object sender, DoWorkEventArgs e)
{
    BackgroundWorker worker = sender as BackgroundWorker;
    EntityCollection<MyEntity> ec =  (EntityCollection<MyEntity>) e.Argument;
    LongRunningTask(ec, worker, e);
}

private void buttonParse_Click(object sender, EventArgs e)
{ 
    this.bgParse.RunWorkerAsync(this.ec);
}

private void LongRunningTask(
EntityCollection<MyEntity> ec, 
BackgroundWorker worker, 
    DoWorkEventArgs e)
{
    while (!worker.CancellationPending)
    {
    for (int i = 0; i < ec.Count; i++)
    {
        MyEntity entity = (MyEntity) ec.Items[i];
        entity.ModifiedDate = DateTime.Now();
    }
    break;
    }
}

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 09-Aug-2006 08:19:09   

An entity is not thread safe. So I think it's better to pass a copy of the entity collection to the background thread.

JimHugh
User
Posts: 191
Joined: 16-Nov-2005
# Posted on: 10-Aug-2006 15:04:28   

Ok, How do I make a copy of the entity collection and entities contained in it?

1) Make a list of all of the PK's and pass them by value and retreive them from the db?

2) Serialize to string, pass string to thread and deserialze?

3) Is there a method on the entity collection that copies the ec already? Wouldn't a copy also exist in the gui thread anyway?

4) Can I pass the entity back in the ProgressReport handler?

5) some documentation that I haven't found?

Sorry if these seem like basic questions and are not specific to LLBLGen, but multi threading is new to me and it is LLBLGen objects that I want to perform work on while keeping a responsive user interface.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39927
Joined: 17-Aug-2003
# Posted on: 12-Aug-2006 13:43:19   

The error you get is likely caused by the fact that if you change an entity in the worker thread, it is marked changed which affects a gui object, namely the bound control(s). These run on another thread.

So I'd unbound the collection from the grid, process it and then rebind it.

Frans Bouma | Lead developer LLBLGen Pro