Laden...

Datei für bearbeitung sperren. Geht das?

Erstellt von Gruppy vor 12 Jahren Letzter Beitrag vor 12 Jahren 5.585 Views
Hinweis von Abt vor 12 Jahren

Vorschoben aus Windows Forms, da offensichtlich eine Webanwendung dahinter steckt.

G
Gruppy Themenstarter:in
9 Beiträge seit 2012
vor 12 Jahren
Datei für bearbeitung sperren. Geht das?

Hallo,

ich habe eine XML-Datei die in Ausnahme fällen schon mal von zwei Usern gleichzeitig geändert werden kann. Seltend, aber kann passieren. Nun möchte ich den Schreibvorgang einmantel wie folgt:

File.SetAttributes(MapPath("test.xml"), FileAttributes.ReadOnly);

bearbeiten der XML
speichern der XML

File.SetAttributes(MapPath("test.xml"), FileAttributes.Normal);

funktioniert das? Kann ich so einen doppelten zugriff verhindern? Arbeitet das alles schnell genug?

1.346 Beiträge seit 2008
vor 12 Jahren

Lass den FileStream nach dem laden doch offen. Dann ist sie gesperrt

G
Gruppy Themenstarter:in
9 Beiträge seit 2012
vor 12 Jahren

Ich nutze den filestream nicht.

ich nutze Xdocument.load und save

wie holt man sich den ne xml mit dem filestream?

1.346 Beiträge seit 2008
vor 12 Jahren

Steht doch alles in der MSDN....

XDocument.Load-Methode (Stream)

G
Gruppy Themenstarter:in
9 Beiträge seit 2012
vor 12 Jahren

Hm ich verstehe das im Moment noch nicht alles.

XDocument Depot = XDocument.Load(MapPath("test.xml"));
 
Depot.Add(new XElement("neues"));
   
Depot.Save(MapPath("test.xml"));

Wenn ich es so schreibe kann es passieren, dass wenn zwei dies gleichzeitig versuchen eine Variante gewinnt und die andere ist weg.
Wie kann ich nun Xdocument.Load offen lassen?

5.742 Beiträge seit 2007
vor 12 Jahren

Wenn ich es so schreibe kann es passieren, dass wenn zwei dies gleichzeitig versuchen eine Variante gewinnt und die andere ist weg

Zwei was? User? Programminstanzen? Prozesse? Threads? Programmierer?
Und was genau meinst du mit "gewinnen" und "weg" sein?

G
Gruppy Themenstarter:in
9 Beiträge seit 2012
vor 12 Jahren

Wie ich schon im Startbeitrag geschrieben meine ich zwei User die gleichzeitig die xml ändern wollen. Dies muß ich verhindern. Das wollte ich erreichen in dem ich die Datei in den Readonly-Modus setze.

16.842 Beiträge seit 2008
vor 12 Jahren

Wenn ich Dein MapPath richtig deute, nutzt Du eine Webapplikation.
Dann wäre aber Windows Forms der falsche Forenbereich.

Du hast also das Problem, dass Du aufgrund der verschiedenen Threads (2 Request - 2 Threads) nicht zeitgleich auf die Datei zugreifen kannst.

Dein Vorhaben ist aber in Deiner Beschreibung widersprüchlich:
Du willst, dass nur einer Schreiben kann (aufgrund des Lockings) aber Du willst auch nicht, dass die Daten aus dem zweiten Request verloren gehen, wenn der erste Request noch aktiv ist.
Dies ist eine Patt-Situation, da Du einen Request nicht warten lassen solltest, was Du aber bei einem gelockten File tun musst, wenn Du die Daten nicht verlieren willst.

Lösung des ganzen ist, außerhalb der beiden Request den Vorgang synchron zu halten.
Sprich Du hast eine Queue, in der die Änderungen reinkommen. Hierbei können aus allen möglichen Threads(analog Requests) die Queue gefüllt werden.
Du hast aber auch noch einen Worker, der die Elemente in der Queue in Deiner Datei aktualisiert / überschreib.

Consumer / Producer Pattern oder SyncQueue <T> - Eine praktische Job-Queue könnte hier der richtige Weg sein.

Eine letzte Sache bleibt: welchen Grund gibt es, dass Du hier eine XML-Datei nutzt oder nutzen musst?
Wofür ist sie gut? Userverwaltung?

G
Gruppy Themenstarter:in
9 Beiträge seit 2012
vor 12 Jahren

Danke für deine lange Antwort.

Also bisher war mein Plan so.

if(!IsFileReadOnly(MapPath("test.xml");

{
File.SetAttributes(MapPath("test.xml"), FileAttributes.ReadOnly);

bearbeiten der XML
speichern der XML

File.SetAttributes(MapPath("test.xml"), FileAttributes.Normal);
}
else
{
System.Threading.Thread.Sleep(3000);
}

Also falls die Datei gesperrt ist warte ich einen Moment und versuche es erneut.

G
Gruppy Themenstarter:in
9 Beiträge seit 2012
vor 12 Jahren

Der Grund für die XML ist die Geschwindigkeit beim laden im gegensatz zu einem mysql Zugriff. Sie besteht nur aus ca. 25 Reihen und das zwei User gleichzeitig drauf zugreifen passiert nur extrem seltend.
Für andere Anwendungen bei Doppelzugriff benutze ich auch mysql.

16.842 Beiträge seit 2008
vor 12 Jahren

Wenn Du die Antworten der anderen liest, dann siehst Du, dass Du lieber einen FileStream nutzen sollst - oder eben eine Queue.
In meinen Augen ist ein Sleep() innerhalb eines Webrequests ein NoGo - egal ob 5ms oder 3000ms.
Der Vorschlag mit dem FileStream stammt aber eher auch nur daher, dass Du nicht gesagt hast, dass Du mit einer Webanwendung arbeitest. Denn Warten ist in der Web-Welt ein rotes Tuch.

Des weiteren kann man beim Zugriff über die Windows API (PInvoke) steuern, ob ein File gelockt ist oder nicht - aber auch davon würde ich abraten.

Du kannst Dir aber auch ein Caching über einen Singleton erstellen.
Hab ich in "Best Practice" für Rechte Caching Webseiten erklärt. Wie der Inhalt dieses Prinzips aussieht, ob hier ein XML oder ein SQL System, ob das nun Benutzerkonten oder andere Daten sind ist egal. Der Singleton sorgt dafür, dass es sauber funktioniert.

Was Du brauchst ist eine Synchronisierung - wie auch immer; ansonsten gehen Dir Daten flöten.

Einige - darunter meine - Fragen beantwortet und erklärt, was Du für ein System, ob Wenanwendung oder nicht, oder Umfeld hast, hast Du aber auch noch nicht.

G
Gruppy Themenstarter:in
9 Beiträge seit 2012
vor 12 Jahren

Hallo,

danke für eure Hilfe. Also es handelt sich um eine Webanwendung. Die Geschwindigkeit spricht für XML, da die Datei nur seltend verändert wird brauche ich auch eigentlich kein Datenbanksystem. In der XML werden nur ein paar Userspezifische Dinge gespeichert, wie ein paar Nutzungszeiten.
Das mit dem Warten ist bei meiner Webanwendung kein Problem, da es im Hintergrund stattfindet.