C# FTP上载-内存泄漏问题

C# FTP上载-内存泄漏问题,c#,memory-leaks,upload,ftp,C#,Memory Leaks,Upload,Ftp,我正在做一个个人项目,使用FTP协议上传和下载大文件。除了我最近注意到的内存泄漏外,它工作正常。我不知道到底是什么问题。可能是内存泄漏或编程错误。上载时,此应用程序使用的内存量每秒都在增加。代码如下: Action action; int bufferSize = 16384; EventLogger elog = new EventLogger(); string error = ""; string filename = ""; public

我正在做一个个人项目,使用FTP协议上传和下载大文件。除了我最近注意到的内存泄漏外,它工作正常。我不知道到底是什么问题。可能是内存泄漏或编程错误。上载时,此应用程序使用的内存量每秒都在增加。代码如下:

    Action action;
    int bufferSize = 16384;
    EventLogger elog = new EventLogger();
    string error = "";
    string filename = "";

    public Uploader(Action action)
    {
        this.action = action;
        filename = action.directory.Substring(action.directory.LastIndexOf('\\') + 1,
            action.directory.Length - action.directory.LastIndexOf('\\') - 1);
    }

    public bool startUpload()
    {   
        try
        {
            FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://*******");
            request.Method = WebRequestMethods.Ftp.ListDirectory;
            request.Credentials = new NetworkCredential("***", "***");

            FtpWebResponse response = (FtpWebResponse)request.GetResponse();

            Stream responseStream = response.GetResponseStream();
            StreamReader reader = new StreamReader(responseStream);
            List<string> files = new List<string>();
            string[] filesArr = reader.ReadToEnd().Split('\n');
            reader.Close();
            response.Close();
            foreach (string file in filesArr)
                files.Add(file.Replace("\r", ""));
            if (files.IndexOf(filename) != -1)
            {
                request = (FtpWebRequest)WebRequest.Create("ftp://***/"+filename);
                request.Method = WebRequestMethods.Ftp.DeleteFile;
                request.Credentials = new NetworkCredential("***", "***");
                response = (FtpWebResponse)request.GetResponse();
                reader.Close();
                response.Close();
                if (response.StatusCode != FtpStatusCode.FileActionOK)
                {
                    return false;
                }
            }

            request = (FtpWebRequest)WebRequest.Create("ftp://***/"+filename);
            request.Method = WebRequestMethods.Ftp.UploadFile;
            request.KeepAlive = false;
            request.UseBinary = true;

            FileStream stream = File.OpenRead(action.directory);
            byte[] buffer = new byte[bufferSize];
            Stream reqStream = request.GetRequestStream();

            SqlCommand cmd = new SqlCommand();
            cmd.CommandText = "update DIRECT_UPLOAD set COMPLETED = @com, PROGRESS = @prog, SPEED = @speed where ID = @id";
            cmd.Parameters.AddWithValue("@id", action.id);
            cmd.Parameters.AddWithValue("@com", 0);
            cmd.Parameters.AddWithValue("@prog", 0);
            cmd.Parameters.AddWithValue("@speed", 0);


            long i = 0;
            int readed = 0;
            int total = 0;
            int speed = 0;
            DateTime last = DateTime.Now;
            int lastTotal = 0;
            while ((readed = stream.Read(buffer, 0, bufferSize)) > 0)
            {
                reqStream.Write(buffer, 0, readed);
                total += readed;
                if (i % 100 == 0)
                {
                    cmd.Parameters["@com"].Value = total;
                    cmd.Parameters["@prog"].Value = (int)(((double)total / action.size) * 100);
                    int tot = 0;
                    tot = total - lastTotal;
                    int time = Convert.ToInt32((DateTime.Now - last).TotalMilliseconds);
                    speed = (int)(((double)1000.0 / time) * tot);
                    cmd.Parameters["@speed"].Value = speed;
                    if ((error = SqlProcess.sqlNonQuery(cmd)) != "")
                        throw new Exception(error);
                    last = DateTime.Now;
                    lastTotal = total;
                }

                Application.DoEvents();
                i++;
            }

            cmd.Parameters["@com"].Value = total;
            cmd.Parameters["@prog"].Value = 100;
            cmd.Parameters["@speed"].Value = 0;
            if ((error = SqlProcess.sqlNonQuery(cmd)) != "")
                throw new Exception(error);

            reqStream.Close();
            stream.Close();
        }
        catch (Exception ex)
        {
            elog.write(ex);
            return false;
        }
        return true;
    }
动作;
int bufferSize=16384;
EventLogger elog=新的EventLogger();
字符串错误=”;
字符串filename=“”;
公共上载程序(操作)
{
这个动作=动作;
filename=action.directory.Substring(action.directory.LastIndexOf(“\\”)+1,
action.directory.Length-action.directory.LastIndexOf('\\')-1);
}
公共bool startupboad()
{   
尝试
{
FtpWebRequest=(FtpWebRequest)WebRequest.Create(“ftp://*******”);
request.Method=WebRequestMethods.Ftp.ListDirectory;
request.Credentials=newnetworkcredential(“***”和“***”);
FtpWebResponse response=(FtpWebResponse)request.GetResponse();
Stream responseStream=response.GetResponseStream();
StreamReader=新的StreamReader(responseStream);
列表文件=新列表();
字符串[]filesArr=reader.ReadToEnd().Split('\n');
reader.Close();
response.Close();
foreach(filesArr中的字符串文件)
files.Add(file.Replace(“\r”,”);
if(files.IndexOf(filename)!=-1)
{
request=(FtpWebRequest)WebRequest.Create(“ftp://***/”+文件名);
request.Method=WebRequestMethods.Ftp.DeleteFile;
request.Credentials=newnetworkcredential(“***”和“***”);
response=(FtpWebResponse)request.GetResponse();
reader.Close();
response.Close();
if(response.StatusCode!=FtpStatusCode.FileActionOK)
{
返回false;
}
}
request=(FtpWebRequest)WebRequest.Create(“ftp://***/”+文件名);
request.Method=WebRequestMethods.Ftp.UploadFile;
request.KeepAlive=false;
request.UseBinary=true;
FileStream stream=File.OpenRead(action.directory);
字节[]缓冲区=新字节[bufferSize];
Stream reqStream=request.GetRequestStream();
SqlCommand cmd=新的SqlCommand();
cmd.CommandText=“更新直接上传集已完成=@com,进度=@prog,速度=@SPEED,其中ID=@ID”;
cmd.Parameters.AddWithValue(“@id”,action.id);
cmd.Parameters.AddWithValue(“@com”,0);
cmd.Parameters.AddWithValue(“@prog”,0);
cmd.Parameters.AddWithValue(“@speed”,0);
长i=0;
int readed=0;
int-total=0;
int速度=0;
DateTime last=DateTime.Now;
int lastTotal=0;
而((readed=stream.Read(buffer,0,bufferSize))>0)
{
请求流写入(缓冲区,0,读取);
总数+=已读;
如果(i%100==0)
{
cmd.Parameters[“@com”].Value=total;
cmd.Parameters[“@prog”].Value=(int)((双精度)总计/action.size)*100);
int-tot=0;
tot=总计-上次总计;
int time=Convert.ToInt32((DateTime.Now-last.total毫秒);
速度=(整数)((双倍)1000.0/次)*tot;
命令参数[“@speed”]。值=速度;
if((error=SqlProcess.sqlNonQuery(cmd))!=“”)
抛出新异常(错误);
last=DateTime.Now;
lastTotal=总计;
}
Application.DoEvents();
i++;
}
cmd.Parameters[“@com”].Value=total;
cmd.Parameters[“@prog”].Value=100;
指令参数[“@speed”]。值=0;
if((error=SqlProcess.sqlNonQuery(cmd))!=“”)
抛出新异常(错误);
reqStream.Close();
stream.Close();
}
捕获(例外情况除外)
{
书面表达(ex);
返回false;
}
返回true;
}

谢谢。

检查您在此处使用的所有对象,确保它们不需要是
Dispose
-d(即它们是否实现
IDisposable
?)。否则,每次执行此代码时,您都会遇到与这些对象中的每个对象关联的非托管资源泄漏

您可以使用
using
整洁地确保以异常安全的方式为此类对象调用
Dispose()

示例-而不是:

SqlCommand cmd = new SqlCommand();
使用此选项包装使用
cmd

using (SqlCommand cmd = new SqlCommand())
{
}
请注意,
EventLogger
类可能还需要实现
IDisposable
,如果它是通过(例如)
文件或
事件日志来包装非托管资源的自定义类


您可以在MSDN文档中检查在此处和程序中其他地方使用的其他内置类。

检查此处使用的所有对象,以确保它们不需要是
Dispose
-d(即它们是否实现
IDisposable
?)。否则,每次执行此代码时,您都会遇到与这些对象中的每个对象关联的非托管资源泄漏

您可以使用
using
整洁地确保以异常安全的方式为此类对象调用
Dispose()

示例-而不是:

SqlCommand cmd = new SqlCommand();
使用此选项包装使用
cmd

using (SqlCommand cmd = new SqlCommand())
{
}
请注意,如果您的
EventLogger
类是包装非托管re的自定义类,则它可能还需要实现
IDisposable