Counter - file - increase access make sure that there are no duplicate numbers - parallel access, multiple

Markus Freitag 3,786 Reputation points
2021-11-27T16:31:03.957+00:00

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?

Azure SQL Database
SQL Server
SQL Server
A family of Microsoft relational database management and analysis systems for e-commerce, line-of-business, and data warehousing solutions.
12,713 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,245 questions
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. 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-primitives

    One 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.0

    For 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, and waitHandle.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();  
    
    1 person found this answer helpful.

  2. Artemiy Moroz 271 Reputation points
    2021-11-30T18:00:17.3+00:00

    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.

    1 person found this answer helpful.