@evilissimo
Im Prinzip ist es eine Art Backup Tool, das Dateien von einer Quelle in einem Ziel sichert. Wenn es nur billiges Kopieren wäre könnte man CopyFile mit FILE_FLAG_WRITE_THROUGH benutzen, um das OS am Cachen zu hindern, aber eine mögliche Operation ist auch das Einpacken in ein Archiv. Dafür lässt sich das Cachen aber leider nicht deaktivieren, sodass ein Aufheben der Connection durch WNetCancelConnection zu unerfreulichen Effekten führen kann (vom simplen "Zugriff verweigert" bis zum bösen "Datenverlust beim Schreiben").
Ich könnte natürlich vor der Ausführung jedes Jobs prüfen, ob er auf die Quelle zugreifen kann (weil der vorherige Job die Verbindung nicht gekappt hat und sie für den aktuellen Job noch besteht). Aber genau das tritt ja nur dann ein, wenn der vorherige Job nicht fehlerfrei abgearbeitet wurde, und davon möchte ich nicht ausgehen, weil es die Ausnahme und nicht die Regel sein soll.
In deinem Beispiel kappst du die Verbindung nur dann, wenn es nötig ist. Ich möchte aber das Gegenteil, nämlich dass die Verbindung nur dann existiert, wenn sie benötigt wird.
Für die ProcessFiles() Details muss ich etwas weiter ausholen:
In einer Queue sind Jobs abgelegt, die bestimmte Operationen ausführen. Jeder Job hat eine Quelle, ein Ziel und optional Zugangsdaten für Quelle und Ziel. Jeder Job hat wiederum eine Queue von Commands, die bestimmte Operationen durchführen, z.B. das Kopieren oder Einpacken von Dateien. Die execute Methode eines Jobs sieht etwa so aus:
void Job::execute()
{
WNetAddConnection2( ... );
try
{
foreach( Command in Commands_ )
{
Command->execute();
}
}
catch( exception& expc )
{
rollback();
}
::WNetCancelConnection2( ... );
}
Die einzelnen Jobs und Commands kennen sich untereinander nicht und können daher auch nicht wissen, ob der Vorgänger die gleichen Zugangsdaten benutzt. Das sollte eigentlich aus so bleiben...
@Martin
Mir ist schon klar, dass die Verbindungen systemweit gelten, deshalb sollten sie auch so kurzlebig wie möglich sein, um Missbrauch zu vermeiden. Im Idealfall sollte die Verbindung nur für die Dauer der Abarbeitung des Jobs bestehen (was dann auch das Problem der maximalen Anzahl der gleichzeitigen Verbindungen löst). Irgendwie verstehe ich deinen Einwand nicht, mir geht´s ja nicht darum, möglichst viele Verbindungen aufzumachen, sondern die Anzahl möglichst klein und kurzlebig zu halten.
Inzwischen habe ich das Problem darauf reduzieren können, dass es tatsächlich am Cachen von Dateioperationen liegt. Man kann WNetCancelConnection2 durch den dritten Parameter erzwingen, und nur in diesem Fall bekomme ich schwere Fehler wie z.B. "Datenverlust beim Schreiben". Also lasse ich zu, dass WNetCancelConnection2 die Verbindung nicht trennt, wenn sie noch benutzt wird. Das verhindert kritische Fehler, lässt eine Verbindung manchmal aber länger leben, als eigentlich notwendig ist. Das führt dann auch manchmal zu Fehler #2 aus meinem Eingangsposting, womit ich aber ganz gut leben kann. Wenn dieser Fehler auftritt wird der Job zurückgesetzt und später ein zweites oder drittes Mal ausgeführt, bis es irgendwann klappt. Ist zwar nicht schön, weil in den Logfiles dann Fehlermeldungen auftauchen, aber das muss ich wohl akzeptieren.