Re: Thank you
Can you confirm that is safe using a session object in a different thread?
The
Session
class is thread safe (will block parallel accesses).
Can you confirm that is safe using a session object in a different thread?
Session
class is thread safe (will block parallel accesses).
private SessionOptions _sessionOptions;
private Session _client;
private Upload(Dictionary<string, string> fileList) {
foreach(var file in fileList) {
SafeExec(() => {
_client.PutFiles(file.Key, file.Value);
});
}
}
private void SafeExec(Action action)
{
// Check client state
if (_client == null || !_client.Opened)
{
// If client connection is not open, explicitly close it and dispose the instance
if (this._client != null)
{
this._client.Close();
this._client.Failed -= _client_Failed;
this._client.Dispose();
this._client = null;
}
// Recreate instance
var sessionOptions = new SessionOptions
{
Protocol = Protocol.Sftp,
HostName = this.host,
UserName = this.username,
Password = this.password,
PortNumber = this.port,
GiveUpSecurityAndAcceptAnySshHostKey = true
};
this._client = new Session();
this._client.ExecutablePath = Path.Combine(GetExecutionFilePath(), "WinSCP.exe"); // set WinSCP.exe path
this._client.SessionLogPath = Path.Combine(GetExecutionFilePath(), "Log\\WinScp.log"); // set session log for issue tracing
this._client.Failed += _client_Failed; // Intercept event for internal logging
// Open instance
_client.Open(this._sessionOptions);
}
// If client is open, execute my delegate
if (_client.Opened)
action.Invoke();
else
throw new SafeExecClientDisconnected();
}
private Upload(Dictionary<string, string> fileList) {
foreach(var file in fileList) {
using(var session = new Session(...)) {
session.Open(...);
_client.PutFiles(file.Key, file.Value);
}
}
}
private SessionOptions _sessionOptions;
private Session _client;
private Upload(Dictionary<string, string> fileList) {
foreach(var file in fileList) {
AsyncSafeExec(() => {
_client.PutFiles(file.Key, file.Value);
});
}
}
private void AsyncSafeExec(Action action) {
var task = Task.Factory.StartNew(() => SafeExec(action));
try {
if(!task.Wait(3600000)) throw new Exception(); // 1 hour timeout
} catch {
// Ignores exceptions or timeouts
_client = null; // Forces client creation for the next call
}
}