I must say that this is a working version:
public async static void SendFileToFtp(string ftpAddress, string ftpUser, string ftpPassword, FileInfo file) { FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(String.Format("{0}{1}", ftpAddress,file.Name)); request.Credentials = new NetworkCredential(ftpUser, ftpPassword); request.KeepAlive = false; request.UseBinary = true; request.Method = WebRequestMethods.Ftp.UploadFile; FileStream fs = File.OpenRead(file.FullName); byte[] sBuffer = new byte[fs.Length]; await fs.ReadAsync(sBuffer, 0, sBuffer.Length); fs.Close(); Stream stream = await request.GetRequestStreamAsync(); await stream.WriteAsync(sBuffer, 0, sBuffer.Length); stream.Close(); } The crux of the matter is whether or not await is too much in this case. Of course, await request should be, but does it make sense to read and write a file with await? (await fs.ReadAsync, await stream.WriteAsync).
As it turned out, this is not redundant, but normal, and only that you can wrap the threads in using. Also, the working version will be such but the problem with the security of running FtpWebRequest will remain.
public async static void SendFileToFtp(string ftpAddress, string ftpUser, string ftpPassword, FileInfo file) { FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(String.Format("{0}{1}", ftpAddress, file.Name)); request.Credentials = new NetworkCredential(ftpUser, ftpPassword); request.KeepAlive = false; request.UseBinary = true; request.Method = WebRequestMethods.Ftp.UploadFile; using (FileStream fs = new FileStream(file.FullName, FileMode.Open)) { byte[] sBuffer = new byte[fs.Length]; await fs.ReadAsync(sBuffer, 0, sBuffer.Length); fs.Close(); using (Stream stream = await request.GetRequestStreamAsync()) { await stream.WriteAsync(sBuffer, 0, sBuffer.Length); stream.Close(); } } } This is solved in an easy way, here is the link with MSDN https://msdn.microsoft.com/ru-ru/library/system.net.ftpwebrequest(v=vs.110).aspx
usingin work with streams, since any of the operations with threads and the request itself can throw an exception and things will not come toclose, and the threads are very desirable to dispose of, regardless of the result of the operation as a whole. - rdorn