Как очистить ресурсы, если FtpWebRequest идет не так - PullRequest
0 голосов
/ 05 ноября 2019

Интересно, если этот FtpWebRequest идет не так, и он идет к событию catch. Я видел пример кода, в котором они опубликовали то, что я раскомментировал в событии catch, - для очистки ресурсов.

Но я не знаю, как правильно сделать это в этом сценарии? Должен ли я просто положить все это: = null;или это неправильно делать? Как правильно это сделать?

cleanUp(sourceStream, ref response, ref requestStream, ref request);

void uploadimage()
        {
            String sourceimage = "C:/ESD/image_2.jpg";
            Task<bool> task = FtpUploadFile(sourceimage);
            if (task.IsFaulted == false)
            {
                MessageBox.Show(task.Result.ToString());
            }
        }
        private Task closeRequestStreamAsync(Stream requestStream) { return Task.Run(() => { requestStream.Close(); }); }
        public async Task<bool> FtpUploadFile(string filename)
        {
            //if exception occurs we want to be able to close these
            FtpWebResponse response = null;
            FtpWebRequest request = null;
            FileStream sourceStream = null;
            Stream requestStream = null;
            try
            {
                bool isimage = false; String ext = Path.GetExtension(filename);
                if (ext == ".jpg" || ext == ".jpeg" || ext == ".png" || ext == ".gif" || ext == ".bmp") { isimage = true; }

                request = (FtpWebRequest)WebRequest.Create("ftp://someurl.com/Folder1/test1.jpg");
                request.UsePassive = true;
                if (isimage == true) { request.UseBinary = true; } //for images
                if (isimage == false) { request.UseBinary = false; } //for text
                request.KeepAlive = true; //keep the connection open
                request.Method = WebRequestMethods.Ftp.UploadFile;
                request.ConnectionGroupName = "Group1";
                request.ServicePoint.ConnectionLimit = 4;

                //These are the credentials.
                request.Credentials = new NetworkCredential("username", "password");


                sourceStream = File.OpenRead(filename);
                byte[] buffer = new byte[sourceStream.Length];
                await sourceStream.ReadAsync(buffer, 0, buffer.Length);
                sourceStream.Close();

                requestStream = await request.GetRequestStreamAsync();
                await requestStream.WriteAsync(buffer, 0, buffer.Length);
                //MPM  This is the call that takes the time     
                await closeRequestStreamAsync(requestStream);

                //response = (FtpWebResponse)request.GetResponse();
                WebResponse responseWeb = await request.GetResponseAsync();
                response = (FtpWebResponse)responseWeb;
                if (response.StatusDescription.Contains("226"))
                {
                    //This means that we successfully have uploaded the file!
                }
                response.Close();
                return true;
            }
            catch (Exception ex)
            {
                string errMSG = string.Format("Upload File failed, exception: {0}", ex.Message);
        //cleanUp(sourceStream, ref response, ref requestStream, ref request);
                return false;
            }
        }

1 Ответ

1 голос
/ 05 ноября 2019

Чтобы гарантировать, что веб-запрос, ответ и объекты потока закрыты, даже если возникает исключение, они должны быть определены в блоке using.

Код можно упростить до:

var ext = Path.GetExtension(filename);
var imageExtensions=new[]{".jpg",".jpeg",".png",".gif",".bmp"};
var isimage = imageExtensions.Contains(ext);

var request = (FtpWebRequest)WebRequest.Create("ftp://someurl.com/Folder1/test1.jpg");

request.UseBinary =isimage;
request.Method = WebRequestMethods.Ftp.UploadFile;
request.ConnectionGroupName = "Group1";
request.ServicePoint.ConnectionLimit = 4;

//These are the credentials.
request.Credentials = new NetworkCredential("username", "password");

using(var sourceStream = File.OpenRead(filename))
using(var requestStream = await request.GetRequestStreamAsync())
{
    await sourceStream.CopyToAsync(requestStream);
}

using(var responseWeb = await request.GetResponseAsync())
{
    var response = (FtpWebResponse)responseWeb;
    if (response.StatusDescription.Contains("226"))
    {
         return true;
    }
}
.....

Я удалил установщики KeepAlive и UsePassive , потому что true является их значением по умолчанию.

Веб-запрос сам по себе не содержит никаких ресурсов, поэтому он не реализует IDisposable. Подключение к серверу осуществляется при вызове GetRequestStream(). Значения, которые необходимо удалить / закрыть: sourceStream, requestStream и responseWeb.

...