FadedAce FadedAce - 1 month ago 6
C# Question

Copying Files Across Network Locations Fast in Debug but Slow With Built Windows Form Application

public partial class ImageCopier : Form {
private BackgroundWorker backgroundWorker = new BackgroundWorker();
public ImageCopier() {
InitializeComponent();
//backgroundWorker.DoWork += Copier_DoWork;
}

private void Form1_Load(object sender, EventArgs e) {
string[] accounts = Directory.GetDirectories("photolocation", "???").Select(d => new DirectoryInfo(d).Name).ToArray();
accountBox.Items.AddRange(accounts);
}

private void copyButton_Click(object sender, EventArgs e) {
if (accountBox.SelectedItems.Count == 0) {
MessageBox.Show("You must select an account.");
}
else {
for (int i = 0; i < accountBox.SelectedItems.Count; i++) {
MessageBox.Show("Starting on account " + accountBox.SelectedItems[i]);
for (int a = 0; a <= 9; a++) {
directoryLabel.Text = "In Folder " + a.ToString();
directoryLabel.Refresh();
string[] files = Directory.GetFiles("photolocation" + accountBox.SelectedItems[i] + "\\photos\\" + a + "\\");
files = files.Where(f => f.Contains('$') != true).ToArray();
if (files.Count() != 0) {
for (int b = 0; b < files.Count(); b++) {
fileLabel.Text = "File " + (b + 1) + " of " + files.Count().ToString();
fileLabel.Refresh();
File.Copy(files[b], files[b].Replace("photolocation", "altlocation"), true);
}
}
else {
MessageBox.Show("Computer does not have read access to image server or there are no photos.");
}
}
MessageBox.Show("Finished account " + accountBox.SelectedItems[i]);
}
//backgroundWorker.RunWorkerAsync();
}
}

private void Copier_DoWork(object sender, DoWorkEventArgs e) {
for (int i = 0; i < accountBox.SelectedItems.Count; i++) {
MessageBox.Show("Starting on account " + accountBox.SelectedItems[i]);
for (int a = 0; a <= 9; a++) {
directoryLabel.Text = "In Folder " + a.ToString();
directoryLabel.Refresh();
string[] files = Directory.GetFiles("photolocation" + accountBox.SelectedItems[i] + "\\photos\\" + a + "\\");
files = files.Where(f => f.Contains('$') != true).ToArray();
if (files.Count() != 0) {
for (int b = 0; b < files.Count(); b++) {
//fileLabel.Text = "File " + (b + 1) + " of " + files.Count().ToString();
//fileLabel.Refresh();
File.Copy(files[b], files[b].Replace("photolocation", "altlocation"), true);
}
}
else {
MessageBox.Show("Computer does not have read access to image server or there are no photos.");
}
}
MessageBox.Show("Finished account " + accountBox.SelectedItems[i]);
}
}
}


The code above is how I'm using it when debugging. I use the backgroundWorker and the Copier_DoWork when it's built, since it just goes Not Responding otherwise. The issue is that when I run it this way Debugging it flies through the files and copies them all within a matter of a few hours. Considering how many images it's copying, that's pretty quick. However, with the background worker it just drags and I estimate it would probably take 35 hours to copy the same amount of files.

I changed the folder location names for this piece of code, but "photolocation" and "altlocation" are two different network computers and locations where the photos need to be duplicated. Most of the images are relatively small, 120kb at the most usually. With a random larger one every now and then.

This is not a huge deal as I just threw this together to take care of an issue that will be fixed after this week by other code, but I'm still curious as to what's causing it to be so much slower. Any help would be appreciated.

Answer

I ended up fixing it by using FileStreams for the starting location and the ending location and CopyTo from the first stream to the second in the backgroundWorker instead of File.Copy and it works much faster, just as fast as File.Copy was working in Debug.