Reputation: 103
i have Command Line
application that received file from user (DOC, PDF), this file is locate on the same machine and my application copy this file to specific folder and return 0 is this operation passed and 1 otherwise.
This command line exe file
can open several times concurrency and there is no problem with it.
Now i want to add to my application a Log
that will locate in the application folder and this Log
will write each file name and if the operation passed or failed.
Now i wonder how to achieve that in case i have several open processes and how to avoid situation that 2 exe files
try to write to my log at the same time.
can i using lock
in such case although i am using several exe files
in the same time ?
Upvotes: 0
Views: 793
Reputation: 1
One of the cleanest and SOA based approach would be to a use a separate logging service which your process ( or processes) will call to log information. Log4Net provides a mechanism for both client and server to post and consume messages respectively. Look at https://log4netremotelogging.codeplex.com/ for further details.
Upvotes: 0
Reputation: 2436
If you don't care too much about the log's cleanliness, you can open the log file in a way that allows multiple processes to write to it:
private static Stream CreateFile(string path, bool checkHost)
{
var mode = FileMode.Append;
return new FileStream(path, mode, FileAccess.Write, FileShare.ReadWrite, 4096, FileOptions.SequentialScan, Path.GetFileName(path), false, false, checkHost);
}
The drawback is that if two processes write to the file concurrently then you'll get a mess that will look like this:
2014-11-26 11:32:93 Suc2014-11-26 11:32:93 Failed: file "Some.doc"
seeded: file "Other.doc"
I.e. the processes race each other and you end up with intermingled log entries. If you don't have too many processes writing to the same log file, and if each process writes infrequently, you should have very few collisions like this.
There are several ways around it. One is to open the file in read-only mode in each process, and wait on other processes until the file is available; the crudest way to do this is to try-catch
a File.AppendAllText()
in a while-loop until you succeed. There are other options listed in questions like this one.
Another alternative is to write log to multiple files, or to something other than file, e.g. to a DB.
Upvotes: 0
Reputation: 1809
You can create named system mutex to control access to log file
// Set this variable to false if you do not want to request
// initial ownership of the named mutex.
bool requestInitialOwnership = true;
bool mutexWasCreated;
// Request initial ownership of the named mutex by passing
// true for the first parameter. Only one system object named
// "MyMutex" can exist; the local Mutex object represents
// this system object. If "MyMutex" is created by this call,
// then mutexWasCreated contains true; otherwise, it contains
// false.
Mutex m = new Mutex(requestInitialOwnership, "MyMutex", out mutexWasCreated);
To ensure there are named mutex you can use Mutex.TryOpenExisting("MyMutex", resultMutex)
and if it exists you can Wait, Log and Release it
resultMutex.WaitOne();
Log("success");
resultMutex.ReleaseMutex();
More info availible in MSDN: http://msdn.microsoft.com/en-us/library/System.Threading.Mutex(v=vs.110).aspx
Upvotes: 2
Reputation: 62093
Do not make a log file. Use ETW and log to the windows mechanisms. It is not like the event log is new (it is there for a long time) and ETW is now fully supported via nuget packages.
ETW also is kernel based.
Upvotes: 1