Paul
Paul

Reputation: 1159

Delegate and dispatcher in a foreach loop can't access current item

I'm trying to implement a progress bar in WPF. I am looping through a list of file paths (List) and performing some operations on the files. I want to track the progress of the process but it is not working correctly. In this case each time the method tagAndMoveFiles() is called it is called with the same item from the foreach list but it is called the proper number of times. I'm not very good with delegates (obviously)...I've included all relevant code. Thanks for your help. (uploadProgress is the progress bar)


        uploadProgress.Maximum = impJob.SourceFilePaths.Count;
        DispatcherTimer timer = new DispatcherTimer();
        int progress = 0;
        foreach (string sourcefilepath in impJob.SourceFilePaths)
        {
            Thread t = new Thread(new ThreadStart(
            delegate()
            {
                    uploadProgress.Dispatcher.BeginInvoke(DispatcherPriority.Loaded,
                    new Action(
                        delegate
                            {
                                tagAndMoveFiles(sourcefilepath, targetFolder, impJob, sourceFileProcessed);
                                uploadProgress.Value = ++progress;
                                Thread.Sleep(100);
                            }
                        ));
            }
            ));
            t.Start();
        }

Upvotes: 1

Views: 938

Answers (2)

Phil Wright
Phil Wright

Reputation: 22956

The delegate is capturing the same instance each time around the loop. So you need to add a local variable inside the loop like this...

foreach(string sourcefilepath in impJob.SourceFilePaths)
{
    string x = sourcefilepath;
    ...
        {
            tagAndMoveFiles(x, ...
        }
    ....
}

Upvotes: 4

ChrisWue
ChrisWue

Reputation: 19060

You ran into this problem: Access to Modified Closure (2)

Short: you need to have a local variable inside your foreach loop to capture the sourcefilepath and pass that to the delegate.

Upvotes: 1

Related Questions