private void OnDownloadProgressAsync(DownloadProgressEventArgs e) { var handler = this.DownloadProgress; if (handler != null) { handler.BeginInvoke(this, e, handler.EndInvoke, null); } }
public async Task<bool> DownloadAsync(FtpFile ftpFile, Stream stream, CancellationToken cancellationToken) { using (await this._mutex.LockAsync(cancellationToken)) { var controlComplexSocket = await this.EnsureConnectionAndAuthenticationAsync(cancellationToken); if (controlComplexSocket == null) { return false; } { var success = await this.GotoParentDirectoryAsync(controlComplexSocket, ftpFile, cancellationToken); if (!success) { return false; } } long bytesTotal; // sending SIZE // reading SIZE { var success = await this.SendAndLogAsync(controlComplexSocket, cancellationToken, "SIZE {0}", ftpFile.FileName); if (!success) { return false; } var ftpReply = await this.ReceiveAndLogAsync(controlComplexSocket, cancellationToken); if (!ftpReply.Success) { return false; } if (!long.TryParse(ftpReply.ResponseMessage, out bytesTotal)) { return false; } } // sending PASV // reading PASV var transferComplexSocket = await this.GetPassiveComplexSocketAsync(controlComplexSocket, cancellationToken); if (transferComplexSocket == null) { return false; } { FtpReply ftpReply; using (transferComplexSocket) { // sending RETR // open transfer socket // reading RETR (150 Opening BINARY mode data connection...) var success = await this.SendAndLogAsync(controlComplexSocket, cancellationToken, "RETR {0}", ftpFile.FileName); if (!success) { return false; } success = await transferComplexSocket.ConnectAsync(cancellationToken); if (!success) { return false; } ftpReply = await this.ReceiveAndLogAsync(controlComplexSocket, cancellationToken); if (!ftpReply.Success) { return false; } { this.WaitBeforeReceive(); // reading transfer socket var rawFtpResponse = await transferComplexSocket.Socket.ReceiveAsync(this.ChunkReceiveBufferSize, transferComplexSocket.GetSocketAsyncEventArgs, cancellationToken, bytesTotal, bytesReceived => { var downloadProgressEventArgs = new DownloadProgressEventArgs(bytesReceived, bytesTotal); this.OnDownloadProgressAsync(downloadProgressEventArgs); }); if (!rawFtpResponse.Success) { return false; } stream.Write(rawFtpResponse.Buffer, 0, rawFtpResponse.Buffer.Length); } } if (!ftpReply.Completed) { // reading RETR (226 Transfer complete) ftpReply = await this.ReceiveAndLogAsync(controlComplexSocket, cancellationToken); if (!ftpReply.Success) { return false; } } } } return true; }