0

I wrote an Async method in C# to write to a file, however I keep on getting the following exception:

The process cannot access the file 'C:\XXX\XXX\XXX\XXX\EventBuffer.txt' because it is being used by another process.

I've had a look at similar questions already posted on SO such as this one, and this one but it seems like the cause of my issue is different.

I used a process monitor to see which processes are trying to access the directory in which the file is in but the only process trying to access it is the one I'm debugging (Will post a snippet soon of the debug process window).

It isn't that file access was being attempted before it was closed upon last access, because I can get the exception when I attempt to access the file for the first time. I have tried to implement a delay after the StreamWriter is instantiated incase the write method was being attempted, I wasn't using the using block before and was disposing of the object using it's dispose methods but in one of the similar questions a this solved the issue.

public static async void UpdateEventBufferFile(EventDetails EventDtls)
{
    string line;

    try
    {
        using (StreamWriter EventBufferFile = new StreamWriter(FilePath, true)) // creates the file
        {
            //All barcode data space sperated for split detection
            line = EventDtls.SiteID + " " + EventDtls.McID + " " + EventDtls.EventID + " "
                 + EventDtls.EventDT + " " + EventDtls.AdditionalInfo;
            await Task.Run(() => LogFileManager.SystematicLog(" Events " + line + " added to buffer file", " BufferFileWriter.cs"));
            await EventBufferFile.WriteLineAsync(line); //no need for new line char WriteLine does that
            await EventBufferFile.FlushAsync();

            //The using block is suffice to dispose of the object the below is no longer required
            //EventBufferFile.Dispose();
            //EventBufferFile.Close();
            //EventBufferFile = null;
        }
    }
    catch (Exception ex)
    {    
    }
}

I have near identical methods utilised within other classes that don't cause the same issue, which annoys me quite a bit.

The method is not being invoked from within a Loop. Invocation is done in a seprate static class in the method below:

    public static void AddCentralEvents(int SiteID, int McID, int EventID, DateTime EventDT, string AdditionalInfo) 
    {
        EventDetails EventDetailsObj = new EventDetails();
        EventDetailsObj.SiteID = SiteID;
        EventDetailsObj.McID = McID;
        EventDetailsObj.EventID = EventID;
        EventDetailsObj.EventDT = EventDT;
        EventDetailsObj.AdditionalInfo = AdditionalInfo;

        Task.Run(() => BufferFileWriter.UpdateEventBufferFile(EventDetailsObj));

    }
Abs
  • 165
  • 1
  • 14

1 Answers1

-2

The error is self explanatory, you are using an ASYNC method (in a loop perhaps) and while your first task hasn't completed it's run (i.e. written to the file) that's why you are ending up with that error.

Have you tried writing with a synchronized method? If you have a requirement to periodically write to a file (i.e. logging) use a logging framework.

I recommend using log4net It is 'one of the' the best out there.

progrAmmar
  • 2,606
  • 4
  • 29
  • 58
  • 1
    "(in a loop perhaps)" is a strong assumption, which should be clarified first. – Mong Zhu Sep 18 '17 at 08:15
  • 1
    "It is the best out there." - Depends on how you define "best". This is opinionated at best ... – Fildor Sep 18 '17 at 08:17
  • I thought so too but that didn't turn out to be the case, to trial this I commented out everything else and kept the using block on it's own, on the first attempt that the using block is executed on I get the exception, therefore there was no operation being done to the file prior to that – Abs Sep 18 '17 at 08:17
  • I may have assumed, but the crux of the answer is that the error occurs due to the file still in process with some Task – progrAmmar Sep 18 '17 at 08:17
  • It isn't being invoked from within a Loop. – Abs Sep 18 '17 at 08:18
  • Why don't you create one task for all and then put await on that? What I mean to say is, create a task that opens the file, writes the line, closes it and destroys resources and put an await on that – progrAmmar Sep 18 '17 at 08:22
  • @progrAmmar And still the FileSystem could keep the file locked for some time after the App closes it and releases the resource. – Fildor Sep 18 '17 at 08:27
  • @Fildor yes you are right, perhaps he should put a check something like a flag `FileInUse`. – progrAmmar Sep 18 '17 at 08:29
  • Thanks, I'll give that a shot. – Abs Sep 18 '17 at 08:41