Raised Ausnahme im Fall des gleichzeitigen Dateizugriff mit Stream
-
29-09-2019 - |
Frage
fand ich eine Post spricht über die gleichzeitige Handhabung von Dateien Zugang mit Stream .
Das Problem ist, dass die Antworten nicht gelingen, das Szenario, in dem die Datei aber mehr Prozessen zugegriffen wird.
Lassen Sie uns sagen, es kurz:
- Ich habe mehrere Anwendungen
- Ich brauche ein zentrales Logging-System in der Datenbank
- Wenn Datenbank fehlschlagen, ich brauche einen Rückfall auf einem Dateisystemprotokoll
Es gibt ein bekanntes Gleichzeitigkeit Szenario, bei dem mehrere Anwendungen (Prozesse) werden versuchen, in dieser Datei zu schreiben. Dies kann durch erneuten Versuch, die Schrift nach einer kurzen Verzögerung verwaltet werden. Aber ich will nicht ot erneuten Versuch, wenn es ein Sicherheitsfehler oder Dateinamen Syntaxfehler ist.
Der Code ist hier:
// true if an access error occured
bool accessError = false;
// number fo writing attemps
int attempts = 0;
do
{
try
{
// open the file
using (StreamWriter file = new StreamWriter(filename, true))
{
// write the line
file.WriteLine(log);
// success
result = true;
}
}
/////////////// access errors ///////////////
catch (ArgumentException)
{
accessError = true;
}
catch (DirectoryNotFoundException)
{
accessError = true;
}
catch (PathTooLongException)
{
accessError = true;
}
catch (SecurityException)
{
accessError = true;
}
/////////////// concurrent writing errors ///////////////
catch (Exception)
{
// WHAT EXCEPTION SHOULD I CATCH HERE ?
// sleep before retrying
Thread.Sleep(ConcurrentWriteDelay);
}
finally
{
attempts++;
}
// while the number of attemps has not been reached
} while ((attempts < ConcurrentWriteAttempts)
// while we have no access error
&& !accessError
// while the log is not written
&& !result);
Meine Frage ist nur die Art der Ausnahme , die im Fall der Gleichzeitigkeit Schriftfelter angehoben werden. Ich weiß schon, kann es auch anders geht. Lassen Sie mich einige Überlegungen hinzufügen:
- Nein, ich will nicht NLog in diesem Szenario verwenden
- Ja, ich handle Gleichzeitigkeit mit IOC + Mutex für die In-Prozess-Gleichzeitigkeit
- Ja, ich möchte wirklich alle Log-in der gleichen Datei geschrieben werden
Lösung
Es wird ein IOException
mit Text sein:
„Der Prozess kann nicht auf die Datei zugreifen‚{0}‘, weil sie von einem anderen Prozess verwendet wird.“
Dies ist ein vereinfachenden Ansatz:
static bool LogError(string filename, string log)
{
const int MAX_RETRY = 10;
const int DELAY_MS = 1000; // 1 second
bool result = false;
int retry = 0;
bool keepRetry = true;
while (keepRetry && !result && retry < MAX_RETRY )
{
try
{
using (StreamWriter file = new StreamWriter(filename, true))
{
// write the line
file.WriteLine(log);
// success
result = true;
}
}
catch (IOException ioException)
{
Thread.Sleep(DELAY_MS);
retry++;
}
catch (Exception e)
{
keepRetry = false;
}
}
return result;
}