As the title says, all I am trying to do (which should be really simple) is open up 20 FTP connections in parallel (all on different threads) and do a single file transfer. This "works" but there are loads of file exceptions that get thrown. The exceptions look like this:
The process cannot access the file 'C:\tmp\ftp_temp\4bb9ec6d-2d32-451f-96b6-b44614cf8372_87.xml' because it is being used by another process.'
I am explicitly setting new XML log and debug log file paths which each new session I open. This should not be happening. I don't get why this is so difficult. This is happening during the
Open
method call on a session.
All methods that use WinSCP use the same
CreateAndOpen
method call:
private Session CreateAndOpenSession(SessionOptions sessionOptions = null)
{
sessionOptions ??= GetDefaultSessionOptions();
var session = CreateSession();
var stopWatch = new Stopwatch();
stopWatch.Start();
session.SessionLogPath = Path.Combine(_agentTempFolderPath, $"{Guid.NewGuid()}_{DateTime.Now.Millisecond}_log.txt");
session.XmlLogPath = Path.Combine(_agentTempFolderPath, $"{Guid.NewGuid()}_{DateTime.Now.Millisecond}.xml");
session.Open(sessionOptions);
stopWatch.Stop();
_logger?.LogInformation($"Took '{stopWatch.Elapsed}' to start/open a new session on the remote server.");
return session;
}
And each call, when run on multiple threads, generates this exception callstack:
System.Private.CoreLib.dll!Microsoft.Win32.SafeHandles.SafeFileHandle.CreateFile(string fullPath, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share, System.IO.FileOptions options)
System.Private.CoreLib.dll!Microsoft.Win32.SafeHandles.SafeFileHandle.Open(string fullPath, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share, System.IO.FileOptions options, long preallocationSize)
System.Private.CoreLib.dll!System.IO.Strategies.OSFileStreamStrategy.OSFileStreamStrategy(string path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share, System.IO.FileOptions options, long preallocationSize)
System.Private.CoreLib.dll!System.IO.Strategies.FileStreamHelpers.ChooseStrategyCore(string path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share, System.IO.FileOptions options, long preallocationSize)
System.Private.CoreLib.dll!System.IO.Strategies.FileStreamHelpers.ChooseStrategy(System.IO.FileStream fileStream, string path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share, int bufferSize, System.IO.FileOptions options, long preallocationSize)
System.Private.CoreLib.dll!System.IO.FileStream.FileStream(string path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share)
WinSCPnet.dll!WinSCP.PatientFileStream.PatientFileStream(WinSCP.Session session, string path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share) Line 9
at C:\s\Github\winscp\dotnet\internal\PatientFileStream.cs(9)
WinSCPnet.dll!WinSCP.SessionLogReader.OpenLog() Line 215
at C:\s\Github\winscp\dotnet\internal\SessionLogReader.cs(215)
WinSCPnet.dll!WinSCP.SessionLogReader.DoRead() Line 102
at C:\s\Github\winscp\dotnet\internal\SessionLogReader.cs(102)
WinSCPnet.dll!WinSCP.SessionLogReader.Read(WinSCP.LogReadFlags flags) Line 65
at C:\s\Github\winscp\dotnet\internal\SessionLogReader.cs(65)
WinSCPnet.dll!WinSCP.CustomLogReader.TryWaitForNonEmptyElement(string localName, WinSCP.LogReadFlags flags) Line 86
at C:\s\Github\winscp\dotnet\internal\CustomLogReader.cs(86)
WinSCPnet.dll!WinSCP.CustomLogReader.WaitForNonEmptyElement(string localName, WinSCP.LogReadFlags flags) Line 98
at C:\s\Github\winscp\dotnet\internal\CustomLogReader.cs(98)
WinSCPnet.dll!WinSCP.Session.Open(WinSCP.SessionOptions sessionOptions) Line 344
at C:\s\Github\winscp\dotnet\Session.cs(344)
I'm using version 5.21.6