Laden...

QuickIO.NET - Performante Dateioperationen

Erstellt von Abt vor 9 Jahren Letzter Beitrag vor 8 Jahren 36.882 Views
Abt Themenstarter:in
16.806 Beiträge seit 2008
vor 9 Jahren
QuickIO.NET - Performante Dateioperationen

Hallo zusammen,

ich möchte euch hier mein QuickIO.NET Projekt vorstellen.

Begonnen hab' ich das ganze ca. 2009 im Rahmen eines Tools um meine NAS-Shares zu visualisieren und immer mal wieder dran rum gebaut.
Anfang dieses Jahres hab ich mich dann intensiv gekümmert und es ganz als Projekt durchgezogen.

Es dient als Erweiterung für den System.IO-Namespace und bietet neben deutlich performanteren Zugriffen auch die Möglichkeit von UNC-Pfaden (Pfadlängen bis 32.767 Zeichen).
Für die Anwendung selbst ändert sich kaum etwas, da ich mich relativ streng an die vorhandenen Außenschnittstellen von System.IO orientiert habe.

Features* Deutliche Performance-Vorteile gegenüber System.IO-Klassen/Methoden (bis zu 30-fach schneller)

  • Direkte, ungefilterte Aufrufe der Win32 API

  • Unterstützung von Pfadlängen bis 32768 Zeichen

  • Transfer-Service: Dateioperationen mit Fortschritts-Information und Condition Monitoring
    Modularisierung in Jobs mit Queue-System, Parallel-Unterstützung und Priorisierung. Mit eigenen Implementierungen erweiterbar.

  • Berechnung von Hashes auf Basis verschiedener Algoriithmen (Sha, MD5..)

  • Parallel zu System.IO nutzbar + einfache Integration in vorhandenen Code durch Methoden-Ersatzung

  • Unterstützung ab .NET 2.0

  • Async-Methoden (ab .NET 4.0)

  • Open Source (Ms-PL)

  • Verfügbar über NuGet

Projektseite mit Beispielen und Online-Dokumentation
http://quickIO.NET

Download
https://quickio.codeplex.com/releases

NuGet
Install-Package QuickIO.NET

Lizenz
Lizenziert ist das ganze als Open Source unter Ms-PL
Verwendung in allen Projekten, egal ob privat oder kommerziell ohne Namensnennung möglich - wär trotzdem nett.

Beispiele (auch auf der Projektseite zu finden)


IEnumerable< QuickIODirectoryInfo > allSubFolders = 
                   QuickIODirectory.EnumerateDirectories( @"C:\temp\QuickIO", SearchOption.AllDirectories );

foreach ( QuickIODirectoryInfo directoryInfo in allSubFolders )
{     
   Console.WriteLine( "Directory found: {0} Readonly: {1}", directoryInfo.FullName, directoryInfo.IsReadOnly );
}


IEnumerable< QuickIOFileInfo > allSubFiles = QuickIODirectory.EnumerateFiles( @"C:\temp\QuickIO", SearchOption.AllDirectories );

foreach ( QuickIOFileInfo fileInfo in allSubFiles )
{     
   Console.WriteLine( "File found: {0} Readonly: {1}", fileInfo.FullName, fileInfo.IsReadOnly );
}

IEnumerable< KeyValuePair< QuickIOPathInfo, QuickIOFileSystemEntryType > > allSubEntries = QuickIODirectory.EnumerateFileSystemEntries( @"C:\temp\QuickIO", SearchOption.AllDirectories ); 

foreach ( KeyValuePair< QuickIOPathInfo, QuickIOFileSystemEntryType > subEntry in allSubEntries )
{     
   var pathInfo = subEntry.Key;     
   var type = subEntry.Value;     

    Console.WriteLine( "Entry found: {0} Readonly: {1}", pathInfo.FullName, type );
}

   QuickIOFolderStatisticResult statsResult = QuickIODirectory.GetStatistics( targetDirectoryPath );

   // Output
   Console.WriteLine( "[Stats] Folders: '{0}' Files: '{1}' Total TotalBytes '{2}'", statsResult.FolderCount, statsResult.FileCount, statsResult.TotalBytes );

PS: der Quellcode wird nächste Woche hochgeladen.
Will noch ein bisschen aufräumen.

Danke auch an Coffeebean, der sich viel anhören und durchlesen musste 😃

Schlagwörter: FastIO, QuickIO, QuickIO.NET, Performance, FileInfo, DirectoryInfo, Copy, Delete, EnumerateFiles, GetFiles, Files, Directories, System.IO, Open Source, MsPL

P
5 Beiträge seit 2013
vor 9 Jahren

Hallo Abt!

Erst mal Danke für die Arbeit, Mühe und das freie zur Verfügung stellen. Auf so eine Bibliothek habe ich gewartet.

Beim meinem ersten Test (dein Beispiel für "Get subfiles") fliegt eine InvalidPathException:

Fehlermeldung:
The directory name is invalid
Path=D:\Downloads\IrgendeinFile.zip

StackTrace:
bei SchwabenCode.QuickIO.Internal.InternalQuickIOCommon.NativeExceptionMapping(String path, Int32 errorCode) in c:_data\SchwabenCode\QuickIO\Dev\QuickIO\Internal\InternalQuickIOCommon.cs:Zeile 147.
bei SchwabenCode.QuickIO.Internal.InternalQuickIO.<EnumerateFiles>d__26.MoveNext() in c:_data\SchwabenCode\QuickIO\Dev\QuickIO\Internal\InternalQuickIO.cs:Zeile 754.
bei SchwabenCode.QuickIO.Internal.InternalQuickIO.<EnumerateFiles>d__26.MoveNext() in c:_data\SchwabenCode\QuickIO\Dev\QuickIO\Internal\InternalQuickIO.cs:Zeile 777.
bei QuickIOTest.Program.Main(String[] args) in d:\Work\QuickIOTest\QuickIOTest\Program.cs:Zeile 16.
bei System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
bei System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
bei Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
bei System.Threading.ThreadHelper.ThreadStart_Context(Object state)
bei System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
bei System.Threading.ThreadHelper.ThreadStart()

Dieser Fehler tritt nur auf, wenn ich über alle Ordner (SearchOption.AllDirectories) suchen möchte. Lasse ich die Option weg, funktioniert es.

Hier mein Code:


        static void Main(string[] args)
        {
            var result = QuickIO.EnumerateFiles(@"d:\Downloads", SearchOption.AllDirectories);
            foreach (var item in result) // Hier kommt die Exception
            {
                Console.WriteLine(item);
            }
            Console.ReadLine();
        }

Achja, Win 7, VS 2013, .NET 4.5

Abt Themenstarter:in
16.806 Beiträge seit 2008
vor 9 Jahren

Korrektur ist hochgeladen.

P
5 Beiträge seit 2013
vor 9 Jahren

Super! Vielen Dank! Läuft. 😃

Abt Themenstarter:in
16.806 Beiträge seit 2008
vor 9 Jahren

Soeben habe ich Version 2.0.0.0 sowohl in NuGet wie auch auf CodePlex aktualisiert.

Changes:* Added new class QuickIOShareInfo

  • Added methods for enumerate network shares
  • Added new class QuickIOFileCompare to compare files
  • Integrated all methods as Async()
  • Added Directory Compress support by using .NET 4.5 FileCompress
  • Added File Compress by GZipStream
  • Native Name Filter support in all EnumerateXYZ()-methods
  • Added general disk information call (total bytes, free bytes of network shares and local disks)
  • Removed doubled methods from class QuickIO. Please use QuickIOFile or QuickIODirectory classes.

Insgesamt hat sich seit der letzten Information hier im Forum einiges getan:
QuickIO.NET Documentation - Version History

Abt Themenstarter:in
16.806 Beiträge seit 2008
vor 9 Jahren

In der dotnet_pro_ 08/2014 Ausgabe, die am 17. Juli erscheint, schreibt Fabian Deitelhoff einen sehr ausführlichen Artikel (5 Seiten) mit Hintergrundinformationen, Beispielen über QuickIO.NET - ich hoffe positives (kenne den Artikel selbst nicht).
Zu finden auf Seite 68 bis 72

742 Beiträge seit 2005
vor 9 Jahren
Hinweis von herbivore vor 9 Jahren

Der Beitrag bezieht sich auf MaskMatch Klasse zum durchsuchen mehrerer Verzeichnisebenen, gehört aber in diesen Thread hier ==> verschoben.

@Abt: Du könntest doch QuickIO abstrahieren, am besten auch sogar so, dass man Azure und S3 abbilden kann. Das hätte ich sehr gerne. Hatte man damit angefangen, aber nie Zeit das richtig zu machen.

Abt Themenstarter:in
16.806 Beiträge seit 2008
vor 9 Jahren

malignate, was Du mit abstrahieren meinst weiß ich nicht; kannst Du mir gerne via PN zukommen lassen.
Für Azure hab ich was eigenes (CDN / Blogs und Co).

D
19 Beiträge seit 2014
vor 9 Jahren

ich bekomme eine: "FileAlreadyExistException" wenn ich eine Datei die es nicht doppelt gibt, vom Desktop in einen von mir erstellten ordner den es ebenfalls nicht doppeltg gibt, kopiere.

Fehlermeldung:
Cannot create a File when that file already Exist

QuickIOFileCopyJob job = new QuickIOFileCopyJob (@"C:\Users\****\Desktop\Neuer Ordner\file.mp3", @"C:\Users\****\Desktop\Ordner", observer);

Bitte um Hilfe

Mfg

Debiii

T
708 Beiträge seit 2008
vor 9 Jahren

Frohes neues Jahr Debiii,

versuch es doch mal wie folgt:

QuickIOFileCopyJob job = new QuickIOFileCopyJob (@"C:\Users\****\Desktop\Neuer Ordner\file.mp3", @"C:\Users\****\Desktop\Ordner\file.mp3", observer);

Sonst versuchst Du eine Datei in einen Ordnernamen zu kopieren.

Gruß
trib

Abt Themenstarter:in
16.806 Beiträge seit 2008
vor 9 Jahren

Korrekt trib; man muss den vollständigen Pfad angeben. So ist ein Umbenennen direkt beim Copy möglich.
Das steht auch in der Doku:

/// <param name="source">Fullname source</param>
/// <param name="target">Fullname target</param>

Und das ist auch im Source, der öffentlich ist, deutlich sichtbar.

protected override void Implementation( )
{
   var sourceInfo = new QuickIOFileInfo( Source );
D
19 Beiträge seit 2014
vor 9 Jahren

Ja, hat sich schon erledigt ^^

@Abt weiss es ja inzwischen 😃 Danke trotzdem !
und euch auch ein frohes neues Jahr 😃)

X
5 Beiträge seit 2015
vor 9 Jahren

Hallo Abt,

Zu aller erst einmal vielen Dank für die Library. Meine Aufgabe ist es ein ca. 12GB großes File von einem Server auf einen USB Stick kopieren.
Mit File.Copy dauerts über eine Stunde, deswegen war ich auf der Suche nach einer anderen Library. (Per NuGet installiert).
Gleich beim Testen stoße ich da auf einen eigenartigen Fehler:
Es sieht so aus, als würde er nach fehlenden Sourcen suchen.

Nullpointer bei QuickIOTransferFileCopyJob:

Namen, Klassen und Pfade wurden verändert.


            QuickIOTransferFileCopyJob copyJob = new QuickIOTransferFileCopyJob(@"\\server\test.ova", @"E:\test.ova", 65535);
            copyJob.Started += OnCopyStarted;
            copyJob.Progress += OnCopyProgress;
            copyJob.Finished += OnCopyFinished;

            copyJob.Run(); <- Hier kommt NPE.

Fehlermeldung:
bei SchwabenCode.QuickIO.Internal.InternalQuickIO.CreateDirectory(QuickIOPathInfo pathInfo, Boolean recursive) in c:_data\Business\CUSTOMERS\SchwabenCode\QuickIO\Dev\QuickIO\Internal\InternalQuickIO.cs:Zeile 134.
bei SchwabenCode.QuickIO.QuickIODirectory.Create(QuickIOPathInfo pathInfo, Boolean recursive) in c:_data\Business\CUSTOMERS\SchwabenCode\QuickIO\Dev\QuickIO\QuickIODirectory_Create.cs:Zeile 93.
bei SchwabenCode.QuickIO.Transfer.QuickIOTransferFileCopyJob.Implementation() in c:_data\Business\CUSTOMERS\SchwabenCode\QuickIO\Dev\QuickIO\Transfer\QuickIOTransferFileCopyJob.cs:Zeile 109.
bei SchwabenCode.QuickIO.Transfer.QuickIOTransferJob.Run() in c:_data\Business\CUSTOMERS\SchwabenCode\QuickIO\Dev\QuickIO\Transfer\QuickIOTransferJob.cs:Zeile 139.

Meine Klasse

bei System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
bei System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
bei Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
bei System.Threading.ThreadHelper.ThreadStart_Context(Object state)
bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
bei System.Threading.ThreadHelper.ThreadStart()

Wie es aussieht hatte PuppetMaster2k auch ein ähnliches Problem, welches du gleich behoben hast.

Vielen Dank im voraus.

PS.: Mir ist auch ein kleiner Fehler in der API von QuickIO aufgefallen:
QuickIO.NET API - QuickIOTransferFileCopyJob
API = Library (Die folgenden Punkte heißen links in der API und rechts in der Library)*CopyStarted = Started *CopyProgress = Progress *CopyFinished = Finished *QuickIOTransferFileCopyFinishedArgs = QuickIOTransferFileCopyFinishedEventArgs *QuickIOTransferFileCopyProgressArgs = QuickIOTransferFileCopyProgressEventArgs *QuickIOTransferFileCopyStartedArgs = QuickIOTransferFileCopyStartedEventArgs

Abt Themenstarter:in
16.806 Beiträge seit 2008
vor 9 Jahren

Das erste Schau ich mir an, das zweite versteh ich nicht, was Du meinst.

EDIT: Kann das sein, dass Du die Eventhandler meinst? Wenn ja, dann ist das Absicht so.
Die Handler zum abonnieren und die On-Methoden zum Feuern von eigenen Elementen.

X
5 Beiträge seit 2015
vor 9 Jahren

Hallo Abt,

Ok, das dürfte ich vielleicht falsch formuliert haben.

Die Klassen und Methoden heissen in der Library anders als dem Codebeispiel, dass du dort angegeben hast:

QuickIO.NET API - QuickIOTransferFileCopyJob

In dem angegebenen Beispiel verwendest du folgendes:

copyJob.CopyStarted += OnCopyStarted;

verwendet muss es aber so werden:

copyJob.Started += OnCopyStarted;

Dass gilt für alle meine angegebenen Beispiele. Ich hoffe das ist jetzt verständlich formuliert.
Deine API war vollkommen in Ordnung, ich bezog mich hier nur auf das Codebeispiel.

PS.: Andere Codebeispiele habe ich mir nicht angesehen, bzw. auf Richtigkeit überprüft.

Abt Themenstarter:in
16.806 Beiträge seit 2008
vor 9 Jahren

Achso. Auf die Beispiele hatte ich gar nicht geachtet.
Ja das kann schon sein, dass das bei einem Rename nicht beachtet wurde 😉
Die Events stammen ja aus der QUelle einer Basis-Klasse und werden nur durchgereicht. Hatte ich bestimmt irgendwann angepasst.

EDIT: Kann das sein, dass Dein E:\ nicht existiert?
Das ist die einzige Stelle, die ich hier nicht bedacht habe und ein Null geworfen werden könnte. Alle anderen Tests werden bei mir erfolgreich durchlaufen.
Zukünftigt wird eine PathNotFoundException geworfen.

X
5 Beiträge seit 2015
vor 9 Jahren

Mein E:\ war beim Test vorhanden, aber dass ist glaub ich nicht das Problem:

Fehlermeldung:
bei SchwabenCode.QuickIO.Internal.InternalQuickIO.:::

bei SchwabenCode.QuickIO.QuickIODirectory.Create(QuickIOPathInfo pathInfo, Boolean recursive) in
c:_data\Business\CUSTOMERS\SchwabenCode\QuickIO\Dev\QuickIO\QuickIODirectory_Create.cs:Zeile 93.
bei SchwabenCode.QuickIO.Transfer.QuickIOTransferFileCopyJob.Implementation() in
c:_data\Business\CUSTOMERS\SchwabenCode\QuickIO\Dev\QuickIO\Transfer\QuickIOTransferFileCopyJob.cs:Zeile 109.
bei SchwabenCode.QuickIO.Transfer.QuickIOTransferJob.Run() in
c:_data\Business\CUSTOMERS\SchwabenCode\QuickIO\Dev\QuickIO\Transfer\QuickIOTransferJob.cs:Zeile 139.

Das Problem dürft sein, dass er ein Verzeichnis/eine Datei nicht findet:
Ich habe hier wieder meine Klassen nicht angefügt und den Stacktrace etwas formatiert

Mein Programm startet vom *H:* Laufwerk (Gemountetes Netzlaufwerk).
Ich weiß als nicht warum die Library versucht auf *c:* zuzugreifen bzw. eine Klasse dort zu suchen.
In meinem *c:* Laufwerk befindet sich kein _data Verzeichnis, auch nicht durch Ändern der "Ordner- und Suchoptionen".

Ich hoffe das wahr jetzt verständlich. 😁

Abt Themenstarter:in
16.806 Beiträge seit 2008
vor 9 Jahren

Das C:\ ist mein Compile-Pfad. Dort liegt auf meiner Kiste dieses Projekt.
Das liegt daran, da die PDB, also die Debug-Dateien mit im Paket enthalten sind. So seh ich bei Fehlermeldungen sehr schnell, ob der Code wirklich auf meinen Mist gewachsen ist oder die Leute irgendwelche Anpassungen auf mich abwälzen wollen 😉
Das hat nichts mit Deiner Kiste oder Deinem Code zutun.

Dein Code ist dieser:

 QuickIOTransferFileCopyJob copyJob = new QuickIOTransferFileCopyJob(@"\\server\test.ova", @"E:\test.ova", 65535);
             copyJob.Started += OnCopyStarted;
             copyJob.Progress += OnCopyProgress;
             copyJob.Finished += OnCopyFinished;

             copyJob.Run(); <- Hier kommt NPE. 

Ich konnte die NullReferenceException nur nachbilden, wenn ich versuche eine Datei direkt auf einem Root-Verzeichnis eines nicht existiertenden Laufwerk zu speichern.

Sprich bei E:\ordner\test.ova wäre der Fehler nicht aufgetreten sondern es hätte eine saubere Exception gegeben.
Wie gesagt; dieser Fall ist jetzt behoben. Suggeriert aber zeitgleich das Du es auf einem Verzeichnis versucht hast, die dieser Fehlerquelle entspricht.

Wenn dies nicht der Fall ist, dann bitte ich Dich den Quellcode von QuickIO.NET zu laden und mal den Debugger anzuwerfen und zu schauen, wo genau die Exception auftritt; also Datei und Zeile.

X
5 Beiträge seit 2015
vor 9 Jahren

Ich habe das Problem gefunden:

Siehe Anhang Screenshot113.png.

Hier greifst du auf parent zu, obwohl es auf null zeigt. Dass wird mit jeder Datei passieren,
die du direkt auf das Rootverzeichnis eines beliebigen Laufwerks kopieren willst.

Edit: Datei: Internal\InternalQuickIO.cs

Abt Themenstarter:in
16.806 Beiträge seit 2008
vor 9 Jahren

Korrekt. Das hab ich auch korrigiert.
Fehlerquelle wie beschrieben 😉

Werde dann heute Abend wohl ein neues Release machen wenns mir reicht.

X
5 Beiträge seit 2015
vor 9 Jahren

Vielen Dank,

aber du hast geschrieben:

Ich konnte die NullReferenceException nur nachbilden, wenn ich versuche eine Datei direkt auf einem Root-Verzeichnis eines nicht existiertenden Laufwerk zu speichern.

Vorhanden war das Laufwerk aber, Deswegen war mir das ganze jetzt nicht so klar.

Abt Themenstarter:in
16.806 Beiträge seit 2008
vor 9 Jahren

Samstag gibts das Update.

S
8 Beiträge seit 2015
vor 8 Jahren

Hi Abt,

eine echt beeindruckende Libary die Du da erstellt hast.

Ich habe nur eine Frage dazu..

mit folgenden Code schaffe ich so Ca. 50MB/s (scr ist eine Netzwerk Quelle)

var copyAsync = QuickIOFile.CopyAsync(scr, desc, true);

aber mit diesen nur so ca. 30MB/s

var copyJob = new QuickIOTransferFileCopyJob(scr, desc, 1024, true);
copyJob.Started += copyJob_Started;
copyJob.Progress += copyJob_Progress;
copyJob.Finished += copyJob_Finished;
copyJob.RunAsync();

mache ich etwas falsch?

Gruß
Shojo

Abt Themenstarter:in
16.806 Beiträge seit 2008
vor 8 Jahren

Die Events verwenden im gleichen Thread ausgeführt wie das eigentliche Kopieren.

Der Ablauf ist also:
- Copy Chunk
- Event-Abarbeitung
- Copy Chunk
- Event-Abarbeitung
 - ....

Die Ausführung wird also leider derzeit gebremst.

Du müsstest also in der Event-Methode die Ausführung deines Codes in einen Task auslagern; also entkoppeln.
Ich hab da irgendwie nicht früher dran gedacht... 😉

QuickIO 3.0 unterstützt dann asynchrone Events.

S
8 Beiträge seit 2015
vor 8 Jahren

Danke für die schnelle Antwort, aber da ist noch nichts drinnen 😉

void copyJob_Finished(object sender, SchwabenCode.QuickIO.Transfer.Events.QuickIOTransferFileCopyFinishedEventArgs e)
{
}

 void copyJob_Progress(object sender, SchwabenCode.QuickIO.Transfer.Events.QuickIOTransferFileCopyProgressEventArgs e)
{
}

void copyJob_Started(object sender, SchwabenCode.QuickIO.Transfer.Events.QuickIOTransferFileCopyStartedEventArgs e)
{
}
Abt Themenstarter:in
16.806 Beiträge seit 2008
vor 8 Jahren

Dann kann ich mir das spontan nicht erklären; evtl. find ich am Wochenende dazu Zeit mir das mal genauer anzuschauen.

S
8 Beiträge seit 2015
vor 8 Jahren

Da danke ich dir schon mal;)

Wäre es auch möglich das man der Funktion ein eigenes Objekt übergeben kann,
auf das man dann wieder in den Events zugreifen kann (wie bei den WebClient().DownloadFileAsync()).

Abt Themenstarter:in
16.806 Beiträge seit 2008
vor 8 Jahren

Ich weiß nicht, was Du meinst oder tun willst.
PS: Ach Du meinst das, was WebClient als token(object) deklariert?
Ich seh da zwar kein Anwendungsfall; aber ich schau mal, ob ich da was typisiertes rein bekomme - Object eher nicht 😉

S
8 Beiträge seit 2015
vor 8 Jahren

Ist das so verständlich?


public void Copyfile(CopyMedia.Media myObj, string des)
{	
	QuickIOTransferfileCopyJob copyJob = new QuickIOTransferfileCopyJob(myObj.scr, des, 1024, true, myObj);

	copyJob.Started += copyJob_Started;
	copyJob.Progress += copyJob_Progress;
	copyJob.Finished += copyJob_Finished;
   
	copyJob.RunAsync();

}

void copyJob_Finished(object sender, SchwabenCode.QuickIO.Transfer.Events.QuickIOTransferfileCopyFinishedEventArgs e)
{
   var myObj = (CopyMedia.Media)e.UserObjekt;
}

void copyJob_Progress(object sender, SchwabenCode.QuickIO.Transfer.Events.QuickIOTransferfileCopyProgressEventArgs e)
{
	var myObj = (CopyMedia.Media)e.UserObjekt;
}

void copyJob_Started(object sender, SchwabenCode.QuickIO.Transfer.Events.QuickIOTransferfileCopyStartedEventArgs e)
{
	var myObj = (CopyMedia.Media)e.UserObjekt;
}

Gruß
Shojo

Abt Themenstarter:in
16.806 Beiträge seit 2008
vor 8 Jahren

Wie Du das meinst hab ich verstanden - aber ich erkenne dort keinen "Pattern", der mir als valide erscheint.

Ich würde daraus eben eine Business-Klasse machen, das das Media-Objekt als Property hat und Du dann in den Eventklassen darauf zugreifen kannst.

public class MyLogic
{
	public MyMedia Media { get; set; }

	public MyLogic(MyMedia media)
	{
		Media = media;
		
		 QuickIOTransferfileCopyJob copyJob = new QuickIOTransferfileCopyJob(scr, des, 1024, true);

		copyJob.Started += copyJob_Started;
		copyJob.Progress += copyJob_Progress;
		copyJob.Finished += copyJob_Finished;

		copyJob.RunAsync();
	}
	
	void copyJob_Finished(object sender, SchwabenCode.QuickIO.Transfer.Events.QuickIOTransferfileCopyFinishedEventArgs e)
	{	
		var doAny = this.Media
	}
}

Das ist im Gegensatz zu Deinem Code nicht nur typsicher sondern auch testbar.

S
8 Beiträge seit 2015
vor 8 Jahren

Das ist im Gegensatz zu Deinem Code nicht nur typsicher sondern auch testbar.

Ok das Argument leuchtet mir ein, dann vergesse mal meine Anfrage 😉

Gruß
Shojo

Abt Themenstarter:in
16.806 Beiträge seit 2008
vor 8 Jahren

Zum Copy.
CopyAsync führt das ganze über die Windows API (CopyFile Win32) aus. Nichts anderes als die Copy()-Methode in einem Task.

TransferJobs sind Implementierungen von mir, die erst die Datei schrittweise lesen und übertragen (über Streams).
Nach jedem Lesen von standardmäßig einem Chunk, also Dateiabschnitt (Standard 1024 Bytes) wird dieser transferiert.
Ich kann hier Lesen und Schreiben ohne größeren Aufwand nicht parallel machen (Pipeline), da ich .NET 2.0 unterstützen will.
Du kannst versuchen den Chunk zu vergrößern, indem Du den BufferSize im Konstruktor nach oben veränderst.

Der Standard ist 1024 Bytes, da dies der geringste Wert darstellt, der empfohlen wird, da ansonsten der interne Windows Buffer zu oft aufgerufen wird.
Je kleiner der Buffer desto öfter werden die Events aufgerufen und desto genauer sind die berechneten Aussagen zu Laufzeit und Kopiergeschwindigkeit.
Bei neuen Systemen wird 4KB als "üblicher Wert genannt" - vermutlich sollten bei GBit-Anschlüssen im lokalen Netzwerk auch höhere Werte noch zu vernünftigen Aussagen führen.

Letzten Endes wird eine Datei durch das Übertragungsprotokoll sowieso geteilt.
Es bietet sich also an, dass der Chunk so groß ist wie das Frame des Übertragungsprotokolls. So vermeidet man Overhead; aber da gibt es nie eine Pauschale, die man hier anwenden könnte.

S
8 Beiträge seit 2015
vor 8 Jahren

Ich habe nun den Buffer auf 1MB hochgetzt und komme nahe der 50MB/s.

Das Ergebnis ist für mich vollkommen ausreichend, danke für den Support!

Gruß Shojo