Hallo liebe C# Gemeinde,
ich bin noch Neuling in C# und habe gerade mein erstes kleines Programm geschrieben.
Das Programm soll Ordner, Unterordner und die darin enthaltenen Dateien kopieren. Das Programm arbeitet bisher einwandfrei nur hat es Probleme mit dem kopieren von größeren Dateien. Wie schon in anderen Forenbeiträgen schon oft erwähnt wurde hängt natürlich das GUI, sodass ich diese Methode gerne in einen Thread auslagern möchte.
Das Problem ist das der Methode 3 Argumente übergeben werden müssen.
Gibt es denn eine Möglichkeit wie ParameterizedThreadStart die mehr als ein Parameter übergeben kann? Und wie genau funktioniert das mit dem Parameter übergeben das als "object" angegeben muss?
private void DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs)
{
DirectoryInfo dir = new DirectoryInfo(sourceDirName);
DirectoryInfo[] dirs = dir.GetDirectories();
// If the source directory does not exist, throw an exception.
if (!dir.Exists)
{
throw new DirectoryNotFoundException(
"Source directory does not exist or could not be found: "
+ sourceDirName);
}
// If the destination directory does not exist, create it.
if (!Directory.Exists(destDirName))
{
Directory.CreateDirectory(destDirName);
}
// Get the file contents of the directory to copy.
FileInfo[] files = dir.GetFiles();
foreach (FileInfo file in files)
{
// Create the path to the new copy of the file.
string temppath = Path.Combine(destDirName, file.Name);
// Copy the file.
file.CopyTo(temppath, true);
}
// If copySubDirs is true, copy the subdirectories.
if (copySubDirs)
{
foreach (DirectoryInfo subdir in dirs)
{
// Create the subdirectory.
string temppath = Path.Combine(destDirName, subdir.Name);
// Copy the subdirectories.
DirectoryCopy(subdir.FullName, temppath, copySubDirs);
}
}
}
private void button1_Click(object sender, EventArgs e)
{
<-----hier steht noch anderer Code------------>
if (checkBox2.Checked)
{
string targetpath, sourcepath, folder1, folder1a;
sourcepath = prepath + tnum + desktop;
targetpath = target1 + tnum + desktop;
if (Directory.Exists(sourcepath))
{
//ParameterizedThreadStart pts = new ParameterizedThreadStart(this.DirectoryCopy);
//Thread thread = new Thread(pts);
//thread.Start(sourcepath, targetpath, true);
DirectoryCopy(sourcepath, targetpath, true);
folder1 = FileCounter(sourcepath).ToString();
folder1a = FileCounter(targetpath).ToString();
if (folder1 == folder1a)
richTextBox1.Text = richTextBox1.Text+"Kopiervorgang von Desktop erfolgreich!" + Environment.NewLine + "Quelle hat " + folder1 + " Dateien" + Environment.NewLine + "Ziel hat " + folder1a + " Dateien" + Environment.NewLine;
else
richTextBox1.Text = richTextBox1.Text+"Kopieren von Desktop fehlgeschlagen" + Environment.NewLine;
}
else
richTextBox1.Text = richTextBox1.Text + @"Der Quellordner Desktop ist nicht vorhanden!" + Environment.NewLine;
}
Danke schon mal im Vorraus......
Hi,
da es sich bei dem Parameter vom ParameterizedThreadStart um ein object handelt. Kannst du deine drei Variablen einfach in einen Object-Array packen.
Diesen kannst du dann dem Thread übergeben und anschliessend kannst du den Array wieder auflösen.
so ungefähr
string v1;
string v2;
string v3;
object[] arr = new object[3];
arr[1]=v1;
arr[2]=v2;
arr[3]=v3;
....
Thread.Start(arr);
...
private void myThreadMethod(object data)
{
object[] arr = (object[])data;
string v1 = arr[0].ToString();
......
}
Da könnten sich zwar ein paar Syntaxfehler eingeschlichen, aber die wird dein Compiler schon finden =)
Vielleicht gibt es auch noch eine elegantere Methode das zu machen.....
mfg
michlG
wow danke für die schnelle Antwort MichlG.
Ich denke ich hab verstanden wie das mit dem Object funktioniert und danke dir für deine "kleine Aufklärung".
Leider bekomme ich immer noch eine Fehlermeldung:
Fehler 1 Keine Überladung für "DirectoryCopy" stimmt mit dem Delegaten "System.Threading.ParameterizedThreadStart" überein. C:\Documents and Settings\bj1480\My Documents\Visual Studio 2008\Projects\copyfolders\WindowsApplication1\Form1.cs 180 52 WindowsApplication1
mein geänderter Code war:
string overwrite = "true";
object[] arr = new object[3];
arr[1] = sourcepath;
arr[2] = targetpath;
arr[3] = overwrite;
ParameterizedThreadStart pts = new ParameterizedThreadStart(this.DirectoryCopy);
Thread thread = new Thread(pts);
thread.Start(arr);
Die beiden Strings sourcepath und targetpath sind deklariert und mit einem Wert beladen.
Die Deklaration der Methode lautete der Methode:
private void DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs)
Da ich mit Überladungen Datentypen verstehe die nicht in den Übergabeparametern stehen versuchte ich auch folgendes:
bool overwrite = true;
object[] arr = new object[3];
arr[1] = sourcepath;
arr[2] = targetpath;
arr[3] = overwrite;
...was allerdings den gleichen Fehler hervorruft.
Hallo cesharper,
DirectoryCopy darf eben nur einen Parameter vom Typ Objekt bekommen.
herbivore
DirectoryCopy benötigt leider 3 Parameter
private void DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs)
DirectoryCopy benötigt leider 3 Parameter
private void DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs)
nö, nur einen. Da du dieses drei Variablen ja in den object[] gepackt hast deshalb muss das so aussehen:
private void DirectoryCopy(object data)
mfg
michlG
Fehler 1 Der Name "sourceDirName" ist im aktuellen Kontext nicht vorhanden.
.
.
Fehler 3 Der Name "destDirName" ist im aktuellen Kontext nicht vorhanden.
.
.
Fehler 8 Der Name "copySubDirs" ist im aktuellen Kontext nicht vorhanden.
.... nun werden alle übergebenen Parameter nicht gefunden.
Hab ich da etwas überlesen?
using System;
using System.Threading;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void DirectoryCopy(object data)
{
DirectoryInfo dir = new DirectoryInfo(sourceDirName);
DirectoryInfo[] dirs = dir.GetDirectories();
// If the source directory does not exist, throw an exception.
if (!dir.Exists)
{
throw new DirectoryNotFoundException(
"Source directory does not exist or could not be found: "
+ sourceDirName);
}
// If the destination directory does not exist, create it.
if (!Directory.Exists(destDirName))
{
Directory.CreateDirectory(destDirName);
}
// Get the file contents of the directory to copy.
FileInfo[] files = dir.GetFiles();
foreach (FileInfo file in files)
{
// Create the path to the new copy of the file.
string temppath = Path.Combine(destDirName, file.Name);
// Copy the file.
file.CopyTo(temppath, true);
}
// If copySubDirs is true, copy the subdirectories.
if (copySubDirs)
{
foreach (DirectoryInfo subdir in dirs)
{
// Create the subdirectory.
string temppath = Path.Combine(destDirName, subdir.Name);
// Copy the subdirectories.
DirectoryCopy(subdir.FullName, temppath, copySubDirs);
}
}
}
private void button1_Click(object sender, EventArgs e)
{
string v1 =@"c:\test";
string v2 =@"c:\test1";
bool v3=true;
object[] arr = new object[3];
arr[1]=v1;
arr[2]=v2;
arr[3]=v3;
ParameterizedThreadStart pts = new ParameterizedThreadStart(this.DirectoryCopy);
Thread thread = new Thread(pts);
thread.Start(arr);
}
}
}
Hi,
ja das ist klar, dass du da diese Exceptions erhälst, da du die Variablen ja nicht deklariert hast.
private void DirectoryCopy(object data)
{
//Data aufsplitten
object[] arr = (object[])data;
String sourceDirName = arr[0].ToString();
String destDirName = arr[1].ToString();
.......
//... Der Rest der Methode
mfg
michlG
Hallo,
du verwendest in deiner Methode variablen welche nicht existieren. Mach folgendes:
private void DirectoryCopy(object data)
{
string sourceDirName = ( string ) (( object[] ) data )[0];
string destDirName = ( string ) (( object[] ) data )[1];
bool copySubDirs = ( bool ) (( object[] ) data )[2];
.
.
.
}
etwaige Syntaxfehler sind in diesem ungetesteten code selbst zu beheben 🙂
Grüsse,
Egon
egrath's Blog: http://egonrath.eg.funpic.de/wordpress
Hallo cesharper,
siehe auch [Hinweis] Syntaxfehler selbst lösen (Compilerfehlermeldungen).
herbivore
Um das Problem mit dem Down- und Upcasten zu umgehen(fehleranfällig), kann man auch eine spezielle Parameterklasse schreiben. Im Konstruktor werden die Argumente übergeben und als Member gespeichert. Anschließend einen neuen Thread mit einer Funktion aus der Klasse (nicht static) erstellen. In dem Thread kann man mit this auf die entsprechenden Parameter zugreifen. Zu beachten ist, immer eine Instanz als Variable zu speichern, sonst räumt der GC den noch arbeitenden Thread auf.
Es gibt 3 Arten von Menschen, die die bis 3 zählen können und die, die es nicht können...
Hi,
Man kann durchaus mehrere parameter mitgeben. siehe Threading in C#
ich habe die von dir gepostete Seite jetzt dreimal überflogen und dabei habe ich nirgends ein Beispiel gesehen, wo mehrere Parameter übergeben werden.
Kannst du bitte diese Stelle der Seite posten, denn dass das auch mit mehreren Parametern gehen soll ist mir, wie wahrscheinlich auch vielen anderen nicht bekannt.
mfg
michlG
Hallo michlG,
static void Main() {
Thread t = new Thread (delegate() { WriteText ("Hello"); });
t.Start();
}
static void WriteText (string text) { Console.WriteLine (text); }
Die WriteText-Methode könnte beliebige Parameter haben, also auch mehrere. Die Parameter sind praktischerweise zudem typsicher.
herbivore
ich habe die von dir gepostete Seite jetzt dreimal überflogen und dabei habe ich nirgends ein Beispiel gesehen, wo mehrere Parameter übergeben werden.
ergänzend: hier wurden die seit .NET 2.0 neu eingeführten anonymen Delegaten verwendet, dort generiert (zaubert) der Compiler eine entsprechende neue Funktion und ruft diese anschließend auf. Das Tolle daran, alle Member und Variablen sind auch in der neuen Funktion verfügbar
Es gibt 3 Arten von Menschen, die die bis 3 zählen können und die, die es nicht können...