6 Replies - 3298 Views - Last Post: 02 March 2010 - 11:37 PM Rate Topic: -----

#1 PsychoCoder  Icon User is offline

  • Google.Sucks.Init(true);
  • member icon

Reputation: 1642
  • View blog
  • Posts: 19,853
  • Joined: 26-July 07

Simple cross-thread exception [Resolved]

Posted 02 March 2010 - 01:53 PM

Ok, I'm not sure if I'm not getting enough sleep, if I'm over complicating this or or if I'm just plain stupid (Ok someone like Core, MentalFloss or someone come in here and make me feel silly please) but I have a process that can be intensive (depending on what is selected) so I have put it in a BackgroundWorker to prevent the UI from freezing.

I know if you want to do any kind of updating I need to use Invoke but for this I'm not trying to update anything, I'm just trying to loop through all the items in the ListView and it's giving me the standard cross-thread communication Exception (and the ListViewItem does not have an Invoke possibility).

This is the code that is causing the proglem (real simple loop)

foreach (ListViewItem systemFolder in listView1.Items)
{
    //work goes on in here
}



It's the for each loop where the Exception is happening.

Is This A Good Question/Topic? 0
  • +

Replies To: Simple cross-thread exception [Resolved]

#2 janne_panne  Icon User is offline

  • WinRT Dev
  • member icon

Reputation: 428
  • View blog
  • Posts: 1,047
  • Joined: 09-June 09

Re: Simple cross-thread exception [Resolved]

Posted 02 March 2010 - 02:55 PM

I was able to reproduce your problem with this piece of code (a form with listview and button):

        public Form1()
        {
            InitializeComponent();

            listView1.Items.Add("hello");
            listView1.Items.Add("world");

            backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
        }

        void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            List<string> str = new List<string>();
            foreach (ListViewItem item in listView1.Items) {
                str.Add(item.Text);
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            backgroundWorker1.RunWorkerAsync();
        }



My solution was to invoke the ListView like this:

        void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            listView1.Invoke(new ListViewDel(ListViewLoop));
        }

        public delegate void ListViewDel();
        public void ListViewLoop()
        {
            List<string> str = new List<string>();
            foreach (ListViewItem item in listView1.Items) {
                str.Add(item.Text);
            }
        }


Was This Post Helpful? 1
  • +
  • -

#3 lesPaul456  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 173
  • View blog
  • Posts: 729
  • Joined: 16-April 09

Re: Simple cross-thread exception [Resolved]

Posted 02 March 2010 - 03:02 PM

I haven't used the background worker much, but when I did, I either used delegates to update the UI, like janne_panne suggested, or I simply pass the needed data between the threads (fill a list from the background thread, then pass that list back to the UI thread once the work is done).

This post has been edited by lesPaul456: 02 March 2010 - 03:02 PM

Was This Post Helpful? 0
  • +
  • -

#4 MentalFloss  Icon User is offline

  • "ADDICTED"[2:5]
  • member icon

Reputation: 528
  • View blog
  • Posts: 1,397
  • Joined: 02-September 09

Re: Simple cross-thread exception [Resolved]

Posted 02 March 2010 - 03:38 PM

Quote

(Ok someone like Core, MentalFloss or someone come in here and make me feel silly please)


Hehe. Thanks for the props :)

Quote

(fill a list from the background thread, then pass that list back to the UI thread once the work is done)


I second this. Assign the list to the DoWorkEventArgs's Result property and when the RunWorkerCompleted event is raised, it will have access to that list. From there, add each, or bind it, or whatever you have to do, but at this point you should have what you need on the correct thread.

One important thing to remember is to always avoid UI related code in the DoWork handler.
Was This Post Helpful? 0
  • +
  • -

#5 AdamSpeight2008  Icon User is offline

  • MrCupOfT
  • member icon


Reputation: 2271
  • View blog
  • Posts: 9,500
  • Joined: 29-May 08

Re: Simple cross-thread exception [Resolved]

Posted 02 March 2010 - 03:53 PM

I thought you had to the control Listview1 first, to access it parameters.
Was This Post Helpful? 0
  • +
  • -

#6 AdamSpeight2008  Icon User is offline

  • MrCupOfT
  • member icon


Reputation: 2271
  • View blog
  • Posts: 9,500
  • Joined: 29-May 08

Re: Simple cross-thread exception [Resolved]

Posted 02 March 2010 - 04:23 PM

Or pass in the ListView1.Items as an argument to the BackgroundWorker1.RunWorkerAsync Method.
  Me.BackgroundWorker1.RunWorkerAsync(Me.ListView1.Items)


Note you'll need to cast it back to the correct collection type, inside of the DoWork.
Was This Post Helpful? 0
  • +
  • -

#7 PsychoCoder  Icon User is offline

  • Google.Sucks.Init(true);
  • member icon

Reputation: 1642
  • View blog
  • Posts: 19,853
  • Joined: 26-July 07

Re: Simple cross-thread exception [Resolved]

Posted 02 March 2010 - 11:37 PM

See I knew someone would show me how stupid I am lol (Thanks janne_panne lol). I thought there would be a simpler way but that did it (with some slight modification to account for what I'm doing)
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1