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 ?

- 93
- 2
- 14
-
2Have a look at log4net. Do not attempt to recreate the wheel when it has already been created. – Bernd Linde Nov 26 '14 at 14:14
4 Answers
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

- 1,709
- 13
- 27
-
If you do decide to use this technique, use a name other than "MyMutex". In fact, come up with a name that's unlikely to be used by anything else. Something like MyApplicationName.LogFileMutex.Number. So if your app is called "Foo", you'd have something like "Foo.LogFileMutex.8793504". That way you're unlikely to have your system object name collide with any others. – Jim Mischel Nov 26 '14 at 19:36
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.

- 61,059
- 10
- 88
- 148
-
-
No, but .NET 4 is not the current version and you did not add the tag that you need something that works on an outdated version of the framework. – TomTom Nov 26 '14 at 14:23
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.
-
But if one application tries to write while another is currently writing, it will throw an exception. Both applications can have the file open, for writing, but if they both try to *write* at the same instant, one of them will throw an exception. – Jim Mischel Nov 26 '14 at 19:33
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.

- 1