2014-09-12 21 views
5

Sto creando un'applicazione che viSSH.NET Carica più file in modo asincrono getta un'eccezione

  1. elaborare un file CSV,
  2. creare JObject per ogni record in CSV file e salvare il JSON come file txt, e, infine,
  3. caricare tutti i file JSON per SFTP server di

Dopo aver cercato per un libreria gratuita per il 3 ° punto, ho deciso di utilizzare SSH.NET.

Ho creato la seguente classe per eseguire l'operazione di caricamento in modo asincrono.

public class JsonFtpClient : IJsonFtpClient 
{ 
    private string _sfptServerIp, _sfptUsername, _sfptPassword; 

    public JsonFtpClient(string sfptServerIp, string sfptUsername, string sfptPassword) 
    { 
     _sfptServerIp = sfptServerIp; 
     _sfptUsername = sfptUsername; 
     _sfptPassword = sfptPassword; 
    } 

    public Task<string> UploadDocumentAsync(string sourceFilePath, string destinationFilePath) 
    { 
     return Task.Run(() => 
     { 
      using (var client = new SftpClient(_sfptServerIp, _sfptUsername, _sfptPassword)) 
      { 
       client.Connect(); 

       using (Stream stream = File.OpenRead(sourceFilePath)) 
       { 
        client.UploadFile(stream, destinationFilePath); 
       } 

       client.Disconnect(); 
      } 
      return (destinationFilePath); 
     }); 
    } 
} 

Il metodo restituisce un UploadDocumentAsyncTPL Task modo che io possa chiamare per caricare più file in modo asincrono.

io chiamo questo metodo UploadDocumentAsync dal seguente metodo che è in una classe diversa:

private async Task<int> ProcessJsonObjects(List<JObject> jsons) 
{ 
    var uploadTasks = new List<Task>(); 
    foreach (JObject jsonObj in jsons) 
    { 
     var fileName = string.Format("{0}{1}", Guid.NewGuid(), ".txt"); 

     //save the file to a temp location 
     FileHelper.SaveTextIntoFile(AppSettings.ProcessedJsonMainFolder, fileName, jsonObj.ToString()); 

     //call the FTP client class and store the Task in a collection 
     var uploadTask = _ftpClient.UploadDocumentAsync(
       Path.Combine(AppSettings.ProcessedJsonMainFolder, fileName), 
       string.Format("/Files/{0}", fileName)); 

     uploadTasks.Add(uploadTask); 
    } 

    //wait for all files to be uploaded 
    await Task.WhenAll(uploadTasks); 

    return jsons.Count(); 
} 

Anche se i risultati di file CSV in migliaia di record JSON, ma voglio caricare questi in lotti di almeno il 50 Questo ProcessJsonObjects riceve sempre un elenco di 50 JObject s alla volta che voglio caricare in modo asincrono sul server SFTP. Ma ricevo il seguente errore sulla client.Connect(); riga del metodo UploadDocumentAsync:

Session operation has timed out 

Diminuire la dimensione del lotto per 2 funziona bene, ma a volte genera il seguente errore:

Client not connected. 

ho bisogno di essere in grado di caricare molti file allo stesso tempo. O dimmi se il server IIS o SFTP ha bisogno di configurazione per questo tipo di operazione e che cos'è.

Cosa sto sbagliando? Il tuo aiuto è molto apprezzato.

+0

Sembra molto probabile che il tuo host FTP ti limiti a 2 connessioni simultanee per client, se riesci a far funzionare la cosa quando diminuisci a 2 client alla volta. –

+0

sì .. questo è quello che ho pensato prima. ma a volte questo non funziona anche con 2 caricamenti simultanei e genera il secondo errore. – Aamir

+0

L'host FTP ti sta limitando e, a volte, se l'host è troppo occupato (che serve altri client), potrebbe non rispondere. Anche caricare 50 file è una cattiva logica, idealmente, dovrebbe essere tutto compresso in un unico file e un file dovrebbe essere caricato, facendo più 50 richieste è spreco di risorse di rete. –

risposta

2

Il modello è completamente danneggiato.

Non stai aspettando nei luoghi corretti e non ti stai unendo ai posti corretti che dovrebbero essere prima di inviare per ridurre la latenza.

L'errore non connesso è perché il collegamento è terminato prima della connessione.

Errore su quelli più grandi perché non si invia nulla per troppo tempo.

+0

Grazie @ Jay. Puoi per favore provare a guidarmi attraverso un codice? Non capisco cosa intendi. Puoi mostrarmi modificando il codice che ho scritto. – Aamir

+0

Effettua i join prima della connessione. Fai un singolo caricamento. Fatto. – Jay

+0

Si potrebbe avere scritto codice C# o incollato/modificato il mio per essere più specifico. – Aamir

Problemi correlati