All I want to do is use one session per thread
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:
All methods that use WinSCP use the same
And each call, when run on multiple threads, generates this exception callstack:
I'm using version 5.21.6
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 theThe process cannot access the file 'C:\tmp\ftp_temp\4bb9ec6d-2d32-451f-96b6-b44614cf8372_87.xml' because it is being used by another process.'
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; }
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)