2

Bit of a problem with a class I'm writing at the moment. I have it set up to write to file very regularly but in a single thread and currently I'm getting hit with the error message: The process cannot access the file because it is being used by another process. This happens regularly but not consistently - if I run it enough times it will break but there's no pattern as to when it breaks.

I've addressed all of the usual culprits here - I'm not using any System.Io.File methods which would return a FileStream so there's nothing that should need to be closed between calls. On top of that I'm testing a generic, single-threaded data structure class in a very stripped down environment - I'm certainly not using multi-threading intentionally and there's nothing in my debug windows to suggest that I'm using it unintentionally either. I'm working on files which exist only for the sake of this test, so I'm virtually 100% sure that nothing else is accessing them.

So I'm at a bit of a loss really. Any thoughts as to why this may be happening? If not, any suggestions as to an efficient workaround would also be appreciated.


Simplified Example

Main method:

static void Main(string[] args)
{
    DiskMap<string> testMap = new DiskMap<string>("C:\path");

        for (int i = 0; i < 100000; i++)
        {
            testMap.Add("a" + i, "aa" + i);
        }
}

Class:

public class DiskMap<TValue>
{
    private string path;
    private int loadedDictionaryId;
    private Dictionary<string, TValue> loadedDictionary;

    public DiskMap(string path)
    {
        this.limit = limit;
        this.path = path;
        File.WriteAllText(path + "\\0.txt", "{");
        File.WriteAllText(path + "\\1.txt", "{");

        loadedDictionary = new Dictionary<string, TValue>();
        loadedDictionaryId = 0;
    }

    public void Add(string key, TValue value)
    {
        int dictionaryId = GetId(key); // returns 0 or 1 in this example
        if (dictionaryId == loadedDictId)
        {
            loadedDict.Add(key, value);
        }
        else
        {
            string filePath = this.path + "\\" + dictionaryId + ".txt";
            File.AppendAllText(filePath, JsonConvert.SerializeObject(key) + ":" + JsonConvert.SerializeObject(value) + ","); // It breaks at this line
        }
    }
}
EmmaO91
  • 408
  • 1
  • 4
  • 18
  • 1
    My first suspicion is antivirus.. however, its quite a simple thing to add a try and catch and to try again until successful or x time has passed. or y tries.. – BugFinder Apr 25 '18 at 14:09
  • There is a Question on SO about awaiting rights to write: https://stackoverflow.com/questions/50744/wait-until-file-is-unlocked-in-net?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa – Smartis has left SO again Apr 25 '18 at 14:11
  • 1
    With File.AppendAllText, I would not call it in a loop, because this will create a StreamWriter and dispose it again and again, reducing performance. And maybe this also causes the issue. You could use StreamWriter instead. – L-Four Apr 25 '18 at 14:13
  • put a try catch around that block and use `tasklist /m path\filename.extension` to find out which process is using it. you might have to do this multiple times since the file might get unlocked when you enter the catch block – Steve Apr 25 '18 at 14:24
  • Okay so. BugFinder: Yeah try-catch may be the way to go, just feels like it shouldn't be necessary given the documentation for File.Append.... Maybe you're right about anti-virus though, I may try flicking it off and see if that makes a difference. Smartis: That's a decent template if I go down the try-catch route instead of identifying the cause. Still would like to know why it's happening though if poss. – EmmaO91 Apr 25 '18 at 14:24
  • L-Four: Not using it in a loop is something I'm planning to look into later but for now I just want to get it working this way. There's good reasons for this but they're not relevant to the issue I'm having. Steve: I tried that command but I just get "INFO: No tasks are running which match the specified criteria." back (even when the application is running and regularly writing to the file). Running in elevated command prompt. – EmmaO91 Apr 25 '18 at 14:33

0 Answers0