All I want to do is use one session per thread

Advertisement

sathenzar
Joined:
Posts:
3

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:
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

Reply with quote

Advertisement

sathenzar
Joined:
Posts:
3

Attached debug ifle

I have attached the debug log file as requested.
  • 83b27deb-6aa3-4eb7-99e2-7516f3c04e5b_467_debug.xml (45.3 KB, Private file)
Description: 83b27deb-6aa3-4eb7-99e2-7516f3c04e5b_467_debug.xml

Reply with quote

sathenzar
Joined:
Posts:
3

As a side note, I checked out my program's code that is in production (not using parallel tasks), which uses a shared session object to upload/download all files synchronously, and these exceptions to not occur. The problem only seems to appear when trying to create a new session per thread and performing an action.

EDIT: The above text is not correct. I did some more testing and it does happen with the previous build. It just isn't that noticeable because it only happens once vs when running in parallel it happens for however many threads get run. It is almost like the code to try to open the log file without sharing is useless, because the WinSCP process is always running and always has a write open on the file trying to be used by PatientFileStream.

I don't know if I should be concerned by this behavior, like if it will have the potential to cause corrupted communications back to the winscp .net DLL, giving incorrect errors / output.

Reply with quote

Advertisement

You can post new topics in this forum