C# SFTP Безопасная ручка закрыта
Я только что получил Безопасный дескриптор был закрыт с моим SFTP-кодом, и я впервые вижу эту ошибку. В нем говорится, что ошибка происходит в строке 74, которая содержит этот блок
sftp.Connect();
Мой код для этого заключается в том, что эта ошибка является периодической, поэтому она происходит случайным образом и выделяет метод sftp.connect. Я использую Renci SFTP 2016.
using (var sftp = new SftpClient(sftpConnInfo))
{
sftp.Connect(); // Line 74
StatusUpdate(this, new Types.StatusUpdateEventArgs() { message = "SFTP Service has connected to remote system (" + sftpConnInfo.Host + ":" + sftpConnInfo.Port.ToString() + remotePath + ")", Location = locationName });
StatusUpdate(this, new Types.StatusUpdateEventArgs() { message = "Process initialized at " + processStart.ToShortDateString() + " " + processStart.ToShortTimeString() + "(" + remotePath + ")", Location = locationName });
System.Diagnostics.Debug.WriteLine("SFTP Service has connected to remote system (" + sftpConnInfo.Host + ":" + sftpConnInfo.Port.ToString() + remotePath + ")");
System.Diagnostics.Debug.WriteLine("Process initialized at " + processStart.ToShortDateString() + " " + processStart.ToShortTimeString() + "(" + remotePath + ")");
sftp.ChangeDirectory(remotePath);
var files = sftp.ListDirectory(".");
string elapsedTimeString = "";
TimeSpan timeElapsed;
DateTime start, end;
start = DateTime.Now;
end = DateTime.Now;
//To allow for more flexibility when attempting to recover from a lost connection, we are iterating the entire file collection up front
// Good for simulating file not loaded
foreach(var f in files)
{
//TODO:What was the UTC of the last successful download?
if (!f.IsDirectory)
{
if (f.Name.Length > 3 || f.Name != null)
{
lastThreecharacters = f.Name.Trim().Substring(f.Name.Length - 3);
foreach (var item in _DoNotDownloadList)
{
if (lastThreecharacters == item.Trim().ToLower())
{
fileAllowed = false;
}
}
//Make sure it's not in the "Do not download" list, compare extension here
if (!_DoNotDownloadList.Exists(x => x.ToLower().Equals(f.Name.ToLower())) && fileAllowed == true)
if (f.LastWriteTime.CompareTo(currentDate) >= 0)
summary.RemoteFiles.Add(new Types.RemoteFile() { FileDownloaded = false, FileName = f.Name, FullName = f.FullName, LastWriteTimeUTC = f.LastWriteTimeUtc });
}
}
};
//Add the Referral Orders File For the Current Day
sftp.ChangeDirectory("Referral Order Summary");
files = sftp.ListDirectory(".");
foreach( var f in files)
{
if (!f.IsDirectory)
{
//Make sure it's not in the "Do not download" list
if (!_DoNotDownloadList.Exists(x => x.ToLower().Equals(f.Name.ToLower())))
if (f.LastWriteTime.CompareTo(currentDate) >= 0)
summary.RemoteFiles.Add(new Types.RemoteFile() { FileDownloaded = false, FileName = f.Name, FullName = f.FullName, LastWriteTimeUTC = f.LastWriteTimeUtc });
}
};
StatusUpdate(this, new Types.StatusUpdateEventArgs() { message = sftpConnInfo.Host + ":" + sftpConnInfo.Port.ToString() + remotePath + " has " + summary.RemoteFiles.Count.ToString() + " files to be downloaded", Location = locationName, StatusType = "TotalFilesCount", TotalFilesToDownload = summary.RemoteFiles.Count });
foreach (var f in summary.RemoteFiles)
{
//Are we still connected? If not, reestablish a connection for up to a max of "MaxReconnectAttempts"
if (!sftp.IsConnected)
{
int maxAttempts = Convert.ToInt32(ConfigurationManager.AppSettings["MaxReconnectAttempts"]);
StatusUpdate(this, new Types.StatusUpdateEventArgs() { message = "SFTP Service has been connected from remote system, attempting to reconnect (" + sftpConnInfo.Host + ":" + sftpConnInfo.Port.ToString() + remotePath + " - Attempt 1 of " + maxAttempts.ToString() + ")", Location = locationName });
for (int attempts = 1; attempts <= maxAttempts; attempts++)
{
sftp.Connect();
if (sftp.IsConnected)
{
StatusUpdate(this, new Types.StatusUpdateEventArgs() { message = "SFTP Service - Connection reestablished (" + remotePath + ")", Location = locationName });
break;
}
else
{
if ((attempts + 1) <= maxAttempts)
{
StatusUpdate(this, new Types.StatusUpdateEventArgs() { message = "SFTP Service still disconnected from remote system, preparing another reconnect attempt (" + sftpConnInfo.Host + ":" + sftpConnInfo.Port.ToString() + remotePath + " - Attempt " + (attempts + 1).ToString() + " of " + maxAttempts.ToString() + ")", Location = locationName });
System.Threading.Thread.Sleep(2000);
}
else
{
//Max reconnect attempts reached - end the session and ensure the appropriate "failure" workflow is triggered
connectionLost = true;
}
}
}
}
if (connectionLost)
break;
totalFileCount++;
try
{
if (!System.IO.File.Exists(localSaveLocation + f.FileName))
{
System.Diagnostics.Debug.WriteLine("\tDownloading file " + totalFileCount.ToString() + "(" + f.FileName + ")");
System.IO.Stream localFile = System.IO.File.OpenWrite(localSaveLocation + f.FileName);
//Log remote file name, local file name, date/time start
start = DateTime.Now;
sftp.DownloadFile(f.FullName, localFile);
end = DateTime.Now;
//Log remote file name, local file name, date/time complete (increment the "successful" downloads by 1)
timeElapsed = end.Subtract(start);
runningSeconds += timeElapsed.TotalSeconds;
runningAvg = runningSeconds / Convert.ToDouble(totalFileCount);
estimatedSecondsRemaining = (summary.RemoteFiles.Count - totalFileCount) * runningAvg;
elapsedTimeString = timeElapsed.TotalSeconds.ToString("#.####") + " seconds";
System.Diagnostics.Debug.WriteLine("\tCompleted downloading file in " + elapsedTimeString + " " + "(" + f.FileName + ")");
downloadedFileCount++;
ProcessFileComplete(this, new Types.ProcessFileCompleteEventArgs() { downloadSuccessful = true, elapsedTime = timeElapsed.TotalSeconds, fileName = f.FileName, fullLocalPath = localSaveLocation + f.FileName, Location = locationName, FilesDownloaded = totalFileCount, FilesRemaining = (summary.RemoteFiles.Count - totalFileCount), AvgSecondsPerDownload = runningAvg, TotalSecondsElapsed = runningSeconds, EstimatedTimeRemaining = TimeSpan.FromSeconds(estimatedSecondsRemaining) });
f.FileDownloaded = true;
// throw new System.ArgumentException("Parameter cannot be null", "original");
if (deleteAfterDownload)
sftp.DeleteFile(f.FullName);
localFile.Close();
}
else
{
System.Diagnostics.Debug.WriteLine("\tFile " + totalFileCount.ToString() + "(" + f.FileName + ") already exists locally");
downloadedFileCount++;
ProcessFileComplete(this, new Types.ProcessFileCompleteEventArgs() { downloadSuccessful = true, elapsedTime = 0, fileName = f.FileName + " (File already exists locally)", fullLocalPath = localSaveLocation + f.FileName, Location = locationName, FilesDownloaded = totalFileCount, FilesRemaining = (summary.RemoteFiles.Count - totalFileCount), AvgSecondsPerDownload = runningAvg, TotalSecondsElapsed = runningSeconds, EstimatedTimeRemaining = TimeSpan.FromSeconds(estimatedSecondsRemaining) });
f.FileDownloaded = true;
if (deleteAfterDownload)
sftp.DeleteFile(f.FullName);
}
}
catch (System.Exception ex)
{
//Log the exception (increment the "failed" downloads by 1)
failedFileCount++;
end = DateTime.Now;
timeElapsed = end.Subtract(start);
runningSeconds += timeElapsed.TotalSeconds;
runningAvg = runningSeconds / Convert.ToDouble(totalFileCount);
estimatedSecondsRemaining = (summary.RemoteFiles.Count - totalFileCount) * runningAvg;
System.Diagnostics.Debug.WriteLine("\tFailed downloading file " + totalFileCount.ToString() + "(" + f.FileName + ") - " + ex.Message);
ProcessFileComplete(this, new Types.ProcessFileCompleteEventArgs() { downloadSuccessful = false, elapsedTime = timeElapsed.TotalSeconds, fileName = f.FileName, fullLocalPath = "File not downloaded", Location = locationName, FilesDownloaded = totalFileCount, FilesRemaining = (summary.RemoteFiles.Count - totalFileCount), AvgSecondsPerDownload = runningAvg, TotalSecondsElapsed = runningSeconds, EstimatedTimeRemaining = TimeSpan.FromSeconds(estimatedSecondsRemaining) });
}
}
}
Полное сообщение об ошибке это
Сведения об исключении: безопасный дескриптор был закрыт - в System.Runtime.InteropServices.SafeHandle.DangerousAddRef(Boolean& success) в System.StubHelpers.StubHelpers.SafeHandleAddRef(SafeHandle pHandle, Boolean& success) в System.Security.CryhHata.UtilHD.UE. hHash, данные Byte[], Int32 cbData, Int32 ibStart, Int32 cbSize) в System.Security.Cryptography.SHA1CryptoServiceProvider.HashCore(Byte[] rgb, Int32 ibStart, Int32 cbSize) в System.Security.Chitem для шифрования. [] буфер) в Renci.SshNet.Security.Cryptography.RsaDigitalSignature.Hash(Byte[] вход) в Renci.SshNet.Security.Cryptography.CipherDigitalSignature.Sign(Byte[] ввод) в Renci.SshNet.Security.KeyHostAgorithm (Данные в байтах []) в Renci.SshNet.PrivateKeyAuthenticationMethod.Authenticate(сеанс сеанса) в Renci.SshNet.AuthenticationMethod.Renci.SshNet.IAuthenticationMethod.Authenticate(сеанс ISession) в сеансе Renci.SshNet.nticheut ationState authenticationState, ICollection`1 enabledAuthenticationMethods, SshAuthenticationException& authenticationException) в Renci.SshNet.ClientAuthentication.Authenticate(IConnectionInfoInternal connectionInfo, сеанс ISession) в Rencen.SshNet.ConnectionInfo.A счетной_категории.категория службы сервиса (Renition).) в Renci.SshNet.BaseClient.Connect() в SFTPUtility.SFTP.ConnectToSFTP(ConnectionInfo sftpConnInfo, String remotePath, String localPath, String locationName) в C:\FTPREPO\SFTPUtility\SFTP.cs: строка 74