Wait for file to be freed by process

后端 未结 11 1007
挽巷
挽巷 2020-12-02 14:23

How do I wait for the file to be free so that ss.Save() can overwrite it with a new one? If I run this twice close together(ish), I get a generic GDI+

11条回答
  •  执念已碎
    2020-12-02 15:12

    If you check access before writing to the file some other process might snatch the access again before you manage to do your write. Therefor I would suggest one of the following two:

    1. Wrap what you want to do in a retry scope that won't hide any other error
    2. Create a wrapper method that waits until you can get a stream and use that stream

    getting a stream

    private FileStream GetWriteStream(string path, int timeoutMs)
    {
        var time = Stopwatch.StartNew();
        while (time.ElapsedMilliseconds < timeoutMs)
        {
            try
            {
                return new FileStream(path, FileMode.Create, FileAccess.Write);
            }
            catch (IOException e)
            {
                // access error
                if (e.HResult != -2147024864)
                    throw;
            }
        }
    
        throw new TimeoutException($"Failed to get a write handle to {path} within {timeoutMs}ms.");
    }
    

    then use it like this:

    using (var stream = GetWriteStream("path"))
    {
        using (var writer = new StreamWriter(stream))
            writer.Write("test");
    }
    

    retry scope

    private void WithRetry(Action action, int timeoutMs = 1000)
    {
        var time = Stopwatch.StartNew();
        while(time.ElapsedMilliseconds < timeoutMs)
        {
            try
            {
                action();
                return;
            }
            catch (IOException e)
            {
                // access error
                if (e.HResult != -2147024864)
                    throw;
            }
        }
        throw new Exception("Failed perform action within allotted time.");
    }
    

    and then use WithRetry(() => File.WriteAllText(Path.Combine(_directory, name), contents));

提交回复
热议问题