Wait for file to be freed by process

后端 未结 11 992
挽巷
挽巷 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:16

    Taking the top answer I wrote a similar one, but it's async, non-blocking, awaitable, cancelable (just stop the task) and checks the exception thrown.

    public static async Task IsFileReady(string filename)
        {
            await Task.Run(() =>
            {
                if (!File.Exists(path))
                {
                    throw new IOException("File does not exist!");
                }
    
                var isReady = false;
    
                while (!isReady)
                {
                    // If the file can be opened for exclusive access it means that the file
                    // is no longer locked by another process.
                    try
                    {
                        using (FileStream inputStream =
                            File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.None))
                            isReady = inputStream.Length > 0;
                    }
                    catch (Exception e)
                    {
                        // Check if the exception is related to an IO error.
                        if (e.GetType() == typeof(IOException))
                        {
                            isReady = false;
                        }
                        else
                        {
                            // Rethrow the exception as it's not an exclusively-opened-exception.
                            throw;
                        }
                    }
                }
            });
        }
    

    You can use it in this fashion:

    Task ready = IsFileReady(path);
    
    ready.Wait(1000);
    
    if (!ready.IsCompleted)
    {
        throw new FileLoadException($"The file {path} is exclusively opened by another process!");
    }
    
    File.Delete(path);
    

    If you have to really wait for it, or in a more JS-promise-way:

    IsFileReady(path).ContinueWith(t => File.Delete(path));
    

提交回复
热议问题