Access of ImageList1 from Backgroundworker_DoWork without using any "delegate" with C#

181 Views Asked by At

I have C# System Windows Forms with Net 2 in use (I am only a beginner so please be patient) and want to add Images in a Backgroundworker-Process to an ImageList1 on my Form1 to avoid a GUI freeze while the filename icons from a large directory with 10000+ files are being displayed with file names and icons in a ListView.
The filenames I store in a list and add them in the Backgroundworker-Finished Event with the AddRange method. The Images can't be stored that way or they lose quality. I have to add them in the Backgroundworker-Process directly in the DoWork() event part. And there is the problem: In my free edition of Microsoft Visual Studio 2008 comes a long error message which says something weird like this approximately: Cannot access ImageList1 because it was created in another thread...????.
I opened a Microsoft ticket and they answered me, that this is a problem of the free version, a bug. Is that so or can you help me. I found something in Google about any "delegates" but I am afraid I know to little to make use of such a construct. I just know how to declare an "int", a string and a list, more not and I can place some usercontrols on my form or fill some simple code in an event. Maybe someone of you has a similar problem and can come up with an exact in place understandable solution ready to use. How would I suppress that error about the other thread in the ImageList? Maybe there exist in C# a statement like "On Error Resume Next" which enforces the code to continue no matter what. Then many VB6 applications would be able to run on Sharp again, dunno ofc. Please help.

2

There are 2 best solutions below

0
On

This is one way to do it:

  1. Create an Action, and put codes that access ImageList1 in the Action.
  2. On Background worker's DoWork, replace codes that have been moved to Action, with ImageList1.Invoke(ActionNameHere).

Here is a simplified example, the code will update a Label's Text property from backgroundworker:

Action act = () =>
              {
                  label1.Text = "Test updating UI property from background thread";
              };
worker.DoWork += (o, args) =>
             {
                 label1.Invoke(act);
             };
worker.RunWorkerAsync();
0
On

You did not post your code, so this a snippet I suggest you could use, it should work:

When using backgroundWorker, it is always convenient for me to use @Keith template

BackgroundWorker bw = new BackgroundWorker { WorkerReportsProgress = true };

bw.DoWork += (sender, e) => 
   {
       //what happens here must not touch the form
       //as it's in a different thread

        Action AccessImageList = () => { int count = imgLst.Images.Count;//access the image list };
        this.Invoke(AccessImageList, new object[] { });
   };

bw.ProgressChanged += ( sender, e ) =>
   {
       //update progress bars here
   };

bw.RunWorkerCompleted += (sender, e) => 
   {
       //now you're back in the UI thread you can update the form
       //remember to dispose of bw now
   };

worker.RunWorkerAsync();