Unstable and floating exception with the access of the file after reading it in Image.NewFromFile
See original GitHub issueHi @kleisauke!
I got an exception and think that it relates to the implementation of NetVips (or LibVips) System.IO.IOException: The process cannot access the file ‘test-X.png’ because it is being used by another process
Explanation
So, we got an unstable and floating exception with the access of the file that was created via System.Diagnostics.Process in async operation and which was read in Image.NewFromFile after that.
So for the reproducing, needs 3 things:
- creates files in the async method via System.Diagnostics.Process in some temp directory
- read files via Image.NewFromFile
- try to delete the temp directory
The exception occurs on deleting the temp directory on the 3 step.
Why I think the issue relates to the NetVips (libvips).
-
The first reason, if I do not read files via Image.NewFromFile (2 step), then deletion temp directory works stable and well.
-
The second reason… If I do:
Image.NewFromBuffer(File.ReadAllBytes(filePath), access: Enums.Access.Sequential)
instead ofImage.NewFromFile(filePath, access: Enums.Access.Sequential)
the code works stable and well also (no exception).
Resources for reproducing
Bellow, I listed the full test code where you can reproduce the issue.
Also, here the project with test code for easy reproducing: TestNetVipsAsync.zip
This is the test picture (test.png) needed for this test:
Important! For reproducing this issue, the test picture must be quite small (as I created).
Full test example
(Please, create the directory C:\Temp\TestNetVips and put there the picture test.png)
static async Task Main(string[] args)
{
Console.WriteLine("Hello NetVips!");
string basePath = "C:\\Temp\\TestNetVips\\";
Directory.SetCurrentDirectory(basePath);
var testPngFile = "test.png";
var testDirectory = "TestDirectory";
Directory.CreateDirectory(testDirectory);
// Prepare 50 test files (clone 50 from test.png)
for (int i = 0; i < 50; i++)
File.Copy(testPngFile, Path.Combine(testDirectory, $"test-{i}.png"), true);
async Task DoAll(string tempDirectory)
{
try
{
// prepare directory for converting
Directory.CreateDirectory(tempDirectory);
// Create test files for converting via external process
// System.Diagnostics.Process
using (var proc = Process.Start(new ProcessStartInfo
{
FileName = "xcopy",
Arguments = $"/S /E /Q /Y {basePath}\\{testDirectory}\\*.* {Path.Combine(basePath, tempDirectory) }\\*.*\r\n",
WorkingDirectory = "C:\\Temp",
UseShellExecute = false,
CreateNoWindow = true
}))
{
proc?.WaitForExit();
}
// Do any await operation to make method really async and run it in different thread
await File.ReadAllBytesAsync("test.png");
// Ensure we are in different threads
Debug.WriteLine($"Work with {tempDirectory} in {Thread.CurrentThread.ManagedThreadId} thread");
// Open files for converting
foreach (var filePath in Directory.GetFiles(tempDirectory, "test-*.png", SearchOption.TopDirectoryOnly))
{
using (Image image = Image.NewFromBuffer(File.ReadAllBytes(filePath), access: Enums.Access.Sequential))
{
// Do nothing, just read, this is already enough for issue
//image.Jpegsave(".....", 75);
}
}
// Delete temp directory !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// Here sometimes unexpectedly we got (this is an issue):
// "System.IO.IOException: The process cannot access the file 'test-X.png' because it is being used by another process"
Directory.Delete(tempDirectory, true);
}
catch (Exception e)
{
Debug.WriteLine(e);
throw;
}
}
try
{
// 10 iteration because the exception not stable
for (int i = 0; i < 10; i++)
{
// 20 parallel tasks for reading files via NetVips
var tasks = new List<Task>();
for (int j = 0; j < 20; j++)
tasks.Add(DoAll($"TempDirectory-{i}-{j}"));
await Task.WhenAll(tasks);
}
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
Issue Analytics
- State:
- Created 2 years ago
- Comments:20 (13 by maintainers)
NetVips.Native v8.12.1 is now available.
PR https://github.com/libvips/libvips/pull/2497 should fix this. The pre-compiled libvips Windows binaries build from that PR can be downloaded here (for testing purposes): https://libvips-packaging.s3.amazonaws.com/vips-dev-w64-web-8.12.0-29fb557-static.zip