hi there! You must open the file with share deny all flag set: https://iq.direct/blog/335-access-single-file-from-different-threads-or-processes-and-maintain-consistensy-without-using-extra-locks.html
The idea is to use File.Open constructor with the FileShare.None option. This option allows only one thread to access the file (either for reading or writing) and deny all other threads. The other threads should catch IOException and try to access the file subsequently with a random delay.
Counter - file - increase access make sure that there are no duplicate numbers - parallel access, multiple
Hello,
I have an xml file where up to 4 applications can access. There must never be the same numbers. How can I just ensure that, what does the implementation look like?
<EANCODING>
<CURRENTCOUNTER value="1230000023129" />
<RESET value="Daily" />
<!-- <RESET value="Weekly" /> -->
<!-- <RESET value="Year" /> -->
<!-- <RESET value="9999999999999" /> -->
<LASTMODIFY value="ApplicationB" />
<DATETIME value="27.11.2021 17:22" />
<STEP value="1" />
<!-- <STEP value="5" /> -->
<!-- <STEP value="10" /> -->
<!-- <STEP value="100" /> -->
</EANCODING>
How can I just test this to prove it works correctly.
Application A opens the file, increases the value and saves it. During this time, the other applications cannot and should not have access. This is very important.
What happens if the file cannot be written or application C cannot close the file. How could I resolve and treat this? What kind of solutions does IT offer here?
2 answers
Sort by: Newest
-
Artemiy Moroz 271 Reputation points
2021-11-30T18:00:17.3+00:00 -
P a u l 10,406 Reputation points
2021-11-28T01:12:04.713+00:00 If you need to maintain consistent read/writing of a single file you have a few options detailed here:
https://learn.microsoft.com/en-us/dotnet/standard/threading/overview-of-synchronization-primitivesOne option is to use
EventWaitHandle
which can be used for inter-process synchronisation:
https://learn.microsoft.com/en-us/dotnet/api/system.threading.eventwaithandle?view=net-6.0For example the application that alters the file might look like this (Writer project):
// The "name" must be unique to your app to avoid collisions. EventWaitHandle waitHandle = new EventWaitHandle(true, EventResetMode.AutoReset, "APPNAME_FILENAME_WAITHANDLE_123"); const string filepath = "..\\..\\..\\..\\Test.txt"; int value = 0; waitHandle.WaitOne(); try { string content = await File.ReadAllTextAsync(filepath); int.TryParse(content, out value); } catch (FileNotFoundException) { // Ignore } value++; Console.WriteLine($"New value: {value}"); await File.WriteAllTextAsync(filepath, value.ToString()); waitHandle.Set();
This reads from the file, parses the content as an int, increments it & resaves it to the file. It surrounds the file access (read and write) with
waitHandle.WaitOne()
(which blocks until the OS signals from another process that the file is free, andwaitHandle.Set()
which signals to the OS that the current process is done with the file.To test this you could add another project to your solution that just starts a few concurrent processes for the executable of the project above (then play around with removing locks to see the issues it prevents) (Tester project):
using System.Diagnostics; Process p1 = Process.Start(new ProcessStartInfo { FileName = "..\\..\\..\\..\\Writer\\bin\\Debug\\net6.0\\Writer.exe", RedirectStandardInput = true, RedirectStandardError = true }); p1.Start(); p1.Start(); p1.Start(); p1.Start();