Frage

Dies ist die Sache, ich möchte eine einfach Anwendung erstellen, die viele Dateien von einem Ort zu kopieren und sie in einer anderen verschieben; aber Asynchron-Methoden verwenden und einen neuen Thread erstellen.

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 ist Wurf! Er sagt, dass ich nicht auf txtdestino Inhalte zugreifen können. Einige Hinweise?

----------------------------------------------- -------------------------------- Edited Dies ist die Version mit allen Änderungen, die gleichen Fehler :( irgendwelche Hinweise?

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); // hier die Ausnahme throw

War es hilfreich?

Lösung

Wenn mehrere Threads versuchen, zuzugreifen (gleichzeitig), um die Datei auf txtdestino.Text - das ist nicht von vornherein zum Scheitern verurteilt? Sie sollten den Inhalt in den Speicher lesen möchten zuerst und schreiben von dort ...

Ebenso Sie gehen, um die IO zu hämmern; Ich frage mich, ob eine praktische Antwort (das löst das Problem oben und unten) ist es, einfach die Kopien tun nacheinander auf den Arbeiter.

Es sieht auch wie man eigentlich die ganze Arbeit hier wieder auf den UI-Thread schieben könnte sowieso ...? sicherlich sollten Sie so etwas wie:

string path = txtdestino.Text;
Thread t = new Thread(new ThreadStart(delegate() {
    foreach (FileInfo Fi in _FileInfoArray) {
        File.Copy(path, Fi.FullName, true);
    }
}));
t.Start();

, die:

  • vermeidet die foreach / capture Ausgabe (Fi nicht erfasst wird)
  • liest den Pfad von dem UI-Thread und verwendet es (captured) auf dem Arbeiter
  • jede Datei verarbeitet sequentiell IO zu vermeiden Hammer

Sie haben auch die foreach / capture Ausgabe; ändern Sie es an:

foreach (FileInfo tmp in _FileInfoArray)
{
    FileInfo Fi = tmp;
    ...

Das Problem ist, dass die meisten wahrscheinlich alle die Fäden zugreifen möchten, die letzte Datei. Nicht wirklich. Dies liegt daran, foreach technisch deklariert die Variable (tmp oben) außerhalb die Schleife; und die variablen Erfassungsregeln (verwendet von Lambda / anon-Methoden) sagen, dass deshalb ist dies der gleich Variable (wichtig: lambda / anon-Methoden sind voll lexikalische Verschlüsse, und erfassen den Variable , nicht Wert ).

Re-Deklaration eine Variable innen die Schleife ändert den Umfang, und jetzt ist das Lambda / Anon-Methode behandelt die Variable als andere pro Schleifeniterationslatenzzeit.

Wenn Sie wirklich wollen, könnte ich es in etwas schreiben, das zeigt die zugrunde liegenden Objekte beteiligt, aber es hängt davon ab, ob Sie so viele Details, wollen; p

Andere Tipps

Anrufe auf UI-Elemente müssen in dem UI-Thread ausgeführt werden. versuchen, den Text-Wert vor der Schleife zu bekommen.

string txt = txtdestino.Text;
foreach (FileInfo Fi in _FileInfoArray)
{
    ....
    File.Copy(txt, Fi.FullName, true);

Sie erstellen mehrere Threads (1 für jede Datei, die Sie finden).
Das Problem ist, dass nur Ihr Hauptthread Ihrer Formularelemente zugreifen kann, sonst alle Fäden Ihre Formularelemente zur gleichen Zeit zu ändern würden.

übergeben Sie den Wert von txtdestino.Text zu Ihrem neuen Thread und Sie sollten in Ordnung sein.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top