Note that there are some explanatory texts on larger screens.

plurals
  1. POUnderstanding using multiple backgroundworkers
    primarykey
    data
    text
    <p>For example purposes, I have a listview that has 3 items in it. Each item contains a column for the path of a folder and a column for the count of the number of files in that folder.</p> <p>If I start a separate backgroundworker to count the files in each of the folders, I get an unexpected result. I think I have tracked the problem down, but I'm not sure how to fix it.</p> <p>In my example below, I've counted the files in each of the folders using two different methods; the first method creates a backgroundworker for each folder with each backgroundworker running concurrently while counting the files. The second method creates one background worker that counts the files in each folder in series. Counting in series does work, while counting concurrently doesn't.</p> <p>The problem seems to be in the method GetPicturesConcurrently(), specifically on the line that reads: </p> <pre><code>fileCounter.DoWork += new DoWorkEventHandler((obj, e) =&gt; CountFilesInFolder(item.Text)); </code></pre> <p>What seems to be happening is that the string that actually gets passed into each call of CountFilesInFolder(string) ends up arriving in the method using the string from the last backgroundworker created; as if the string from item.Text was being passed by reference instead of by value. So I end up counting the files in the same folder over and over again.</p> <p>When I Break at the time of the backgroundworker creation, I can see that the correct string gets passed each time; and when I Break on CountFilesInFolder, the last string entered gets processed for every call.</p> <p>Here is an example that demonstrates the problem:</p> <pre><code>public partial class Form1 : Form { private ConcurrentDictionary&lt;string, int&gt; MyFiles; private List&lt;string&gt; Folders; public Form1() { MyFiles = new ConcurrentDictionary&lt;string,int&gt;(); Folders = new List&lt;string&gt;(); InitializeComponent(); PopulateListview(); } private void PopulateListview() { ListViewItem item1 = new ListViewItem(); ListViewItem item2 = new ListViewItem(); ListViewItem item3 = new ListViewItem(); item1.Text = @"V:\"; item2.Text = @"D:\"; item3.Text = @"C:\"; item1.SubItems.Add(""); item2.SubItems.Add(""); item3.SubItems.Add(""); listView1.Items.Add(item1); listView1.Items.Add(item2); listView1.Items.Add(item3); } private void GetPicturesInSeries() { Reset(); foreach (ListViewItem item in listView1.Items) { Folders.Add(item.Text); } BackgroundWorker fileCounter = new BackgroundWorker(); fileCounter.DoWork += new DoWorkEventHandler((obj, e) =&gt; GetPictures()); fileCounter.RunWorkerCompleted += new RunWorkerCompletedEventHandler((obj, e) =&gt; UpdateCountListView()); fileCounter.RunWorkerAsync(); } private void GetPicturesConcurrently() { Reset(); foreach (ListViewItem item in listView1.Items) { BackgroundWorker fileCounter = new BackgroundWorker(); fileCounter.DoWork += new DoWorkEventHandler((obj, e) =&gt; CountFilesInFolder(item.Text)); fileCounter.RunWorkerCompleted += new RunWorkerCompletedEventHandler((obj, e) =&gt; UpdateCountListView(item.Index)); fileCounter.RunWorkerAsync(); } } private void GetPictures() { foreach (string folder in Folders) { CountFilesInFolder(folder); } } private void CountFilesInFolder(string folder) { DirectoryInfo dirInfo = new DirectoryInfo(folder); IEnumerable&lt;FileInfo&gt; files = dirInfo.EnumerateFiles(); int count = files.Count(); MyFiles.AddOrUpdate(folder, count, (key, oldvalue) =&gt; files.Count()); } private void UpdateCountListView(int index) { string key = listView1.Items[index].Text; int count; MyFiles.TryGetValue(key,out count); listView1.BeginUpdate(); listView1.Items[index].SubItems[1].Text = count.ToString(); listView1.EndUpdate(); listView1.Refresh(); } private void UpdateCountListView() { listView1.BeginUpdate(); foreach (ListViewItem item in listView1.Items) { string key = item.Text; int count; MyFiles.TryGetValue(key, out count); listView1.Items[item.Index].SubItems[1].Text = count.ToString(); } listView1.EndUpdate(); listView1.Refresh(); } private void Reset() { listView1.BeginUpdate(); foreach (ListViewItem item in listView1.Items) { item.SubItems[1].Text = ""; } listView1.EndUpdate(); listView1.Refresh(); Folders.Clear(); MyFiles.Clear(); } } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload