Here is the thing, I want to create a simply app that copy many files from one site, and move them to another; but using async methods and create a new thread.
private void button3_Click(object sender, RoutedEventArgs e)
{
//progressBar1.Maximum = _FileInfoArray.Count;
DispatcherTimer dt1 = new DispatcherTimer();
foreach (FileInfo Fi in _FileInfoArray)
{
Thread t = new Thread(new ThreadStart(delegate()
{
DispatcherOperation _dispOp = progressBar1.Dispatcher.BeginInvoke(DispatcherPriority.Loaded, new Action(delegate()
{
File.Copy(txtdestino.Text, Fi.FullName, true);
//progressBar1.Value = n;
//txtstatus.Content = ("Copiados " + n.ToString() + " archivos");
//Thread.Sleep(100);
}
));
_dispOp.Completed += new EventHandler(_dispOp_Completed);
}
));
t.Start();
}
}
UnauthorizedAccessException is throw! It says that I can’t access to txtdestino content. Some clues?
——————————————————————————-Edited
This is the version with all the changes, get the same error 🙁 any clues?
private void button4_Click(object sender, RoutedEventArgs e)
{
//First: Build mynames
List<string> mynames = new List<string>();
foreach (FileInfo fi in _FileInfoArray)
{
mynames.Add(fi.FullName);
}
Thread t = new Thread(new ThreadStart(delegate()
{
foreach (string fullname in mynames)
{
DispatcherOperation _dispOp = progressBar1.Dispatcher.BeginInvoke(DispatcherPriority.Loaded, new Action(delegate()
{
string destino = System.IO.Path.Combine(@"C:\", System.IO.Path.GetFileName(fullname));
File.Copy(fullname, destino, true);
//Some progressbar changes
}
));
_dispOp.Completed += new EventHandler(_dispOp_Completed);
}
}
));
t.Start();
}
File.Copy(txtdestino.Text, Fi.FullName, true); // here the exception is throw
If multiple threads try to access (simultaneously) the file at
txtdestino.Text– isn’t that doomed from the start? You might want to read the contents into memory first and write from there…Equally, you are going to hammer the IO; I wonder if a more practical answer (that solves the issue above and below) is to simply do the copies sequentially on the worker.
It also looks like you might actually be pushing all the work here back to the UI thread anyway…? surely you should do something like:
which:
Fiis not captured)You also have the foreach/capture issue; change it to:
The problem is that most likely all the threads are trying to access the last file. No, really. This is because
foreachtechnically declares the variable (tmpabove) outside the loop; and the variable capture rules (used by lambdas / anon-methods) say that therefore this is the same variable (important: lambdas / anon-methods are full lexical closures, and capture the variable, not the value).Re-declaring a variable inside the loop changes the scope, and now the lambda / anon-method treats the variable as different per loop iteration.
If you really want, I could write it out in something that shows the underlying objects involved, but it depends whether you want that level of detail ;p