threading in a Custom Collection
-
Hi All, I'd like to make a separate thread in inserting of data into the Custom Collection I have and fires an event when its done so it would be bound to a grid. Is it possible? here is my example code.
public class Details : List<Details.Detail> { public delegate void \_WorkComplete(); public event \_WorkComplete WorkComplete; public void AddDataSource(object value) { Thread worker = new Thread(new ParameterizedThreadStart(dowork)); worker.Start(value); } private void dowork(object value) { ArrayList list = (ArrayList)value; foreach (Item item in list) { this.Add(new Detail { FIELD1 = item.Code1, FIELD2 = item.Code2 }); } if (WorkComplete != null) WorkComplete(); } public class Detail { private string field1; private string field2; public Detail() { field1 = string.Empty; field2 = string.Empty; } public string FIELD1 { get { return field1; } set { field1 = value; } } public string FIELD2 { get { return field2; } set { field2 = value; } } } }
so in the UI side i could do
private Details details = new Details();
protected void Page_Load(object sender, EventArgs e)
{
details.OnWorkComplete += new Details._WorkComplete(details_AddComplete);
details.AddDataSource(source1);
details.AddDataSource(source2);
}void details_AddComplete()
{
grid1.DataSource = details;
grid1.DataBind();
} -
Hi All, I'd like to make a separate thread in inserting of data into the Custom Collection I have and fires an event when its done so it would be bound to a grid. Is it possible? here is my example code.
public class Details : List<Details.Detail> { public delegate void \_WorkComplete(); public event \_WorkComplete WorkComplete; public void AddDataSource(object value) { Thread worker = new Thread(new ParameterizedThreadStart(dowork)); worker.Start(value); } private void dowork(object value) { ArrayList list = (ArrayList)value; foreach (Item item in list) { this.Add(new Detail { FIELD1 = item.Code1, FIELD2 = item.Code2 }); } if (WorkComplete != null) WorkComplete(); } public class Detail { private string field1; private string field2; public Detail() { field1 = string.Empty; field2 = string.Empty; } public string FIELD1 { get { return field1; } set { field1 = value; } } public string FIELD2 { get { return field2; } set { field2 = value; } } } }
so in the UI side i could do
private Details details = new Details();
protected void Page_Load(object sender, EventArgs e)
{
details.OnWorkComplete += new Details._WorkComplete(details_AddComplete);
details.AddDataSource(source1);
details.AddDataSource(source2);
}void details_AddComplete()
{
grid1.DataSource = details;
grid1.DataBind();
}Search in google for cross-thread-exception. You cannot change something in control from another thread. "grid1.DataSource = details;" -> Cross Thread Exception
void details_AddComplete()
{
Invoke(new MethodInvoker(AddComplete));
}void AddComplete()
{
grid1.DataSource = details;
grid1.DataBind();
} -
Search in google for cross-thread-exception. You cannot change something in control from another thread. "grid1.DataSource = details;" -> Cross Thread Exception
void details_AddComplete()
{
Invoke(new MethodInvoker(AddComplete));
}void AddComplete()
{
grid1.DataSource = details;
grid1.DataBind();
}that does not fire an error the "details" is created on the same thread. as the "grid1". not the comment I expected but thanks for the reply.
modified on Wednesday, August 12, 2009 5:07 AM
-
Hi All, I'd like to make a separate thread in inserting of data into the Custom Collection I have and fires an event when its done so it would be bound to a grid. Is it possible? here is my example code.
public class Details : List<Details.Detail> { public delegate void \_WorkComplete(); public event \_WorkComplete WorkComplete; public void AddDataSource(object value) { Thread worker = new Thread(new ParameterizedThreadStart(dowork)); worker.Start(value); } private void dowork(object value) { ArrayList list = (ArrayList)value; foreach (Item item in list) { this.Add(new Detail { FIELD1 = item.Code1, FIELD2 = item.Code2 }); } if (WorkComplete != null) WorkComplete(); } public class Detail { private string field1; private string field2; public Detail() { field1 = string.Empty; field2 = string.Empty; } public string FIELD1 { get { return field1; } set { field1 = value; } } public string FIELD2 { get { return field2; } set { field2 = value; } } } }
so in the UI side i could do
private Details details = new Details();
protected void Page_Load(object sender, EventArgs e)
{
details.OnWorkComplete += new Details._WorkComplete(details_AddComplete);
details.AddDataSource(source1);
details.AddDataSource(source2);
}void details_AddComplete()
{
grid1.DataSource = details;
grid1.DataBind();
}Assuming you add all your sources in Page_Load, you could do this: In AddDataSource, just add the source to a collection inside Details. Add a method Details.StartProcessing() which starts the background work. So Page_Load would look like:
details.AddDataSource( source1 );
details.AddDataSource( source2 );
details.StartProcessing();
}As Stan said, your event will be fired on the background thread. Either use a BackgroundWorker instead of a Thread, or use Invoke before you update the grid. Nick
---------------------------------- Be excellent to each other :)