asp.net mvc应用程序中的文件读写内存泄漏

时间:2015-03-17 12:48:39

标签: c# asp.net-mvc-4 memory-leaks instagram

我从文本文件中读取json字符串并将json字符串转换为object并将其添加到列表中。然后我在循环中调用instagram feed API,在获得响应之后我将响应字符串转换为json对象并将其添加到列表中。最后,我将对象列表转换为json字符串并将其写入文本文件。

我需要在两个文本文件中更新json字符串,因此在完成对instagram的所有请求后,我将json字符串从一个文本文件复制到另一个文本文件。

我的问题

我每10分钟调用一次此InstagramRecentList方法,以反映我网站上最近的Instagram Feed。当我检查服务器中的内存使用情况时,此应用程序池也会在一个阶段占用更多内存,因此,IIS中托管的所有应用程序都会停止运行。上述过程的最佳和有效方法是什么,这样我的应用程序就不会占用更多内存。

Here是屏幕截图,所选进程显示该应用程序池的内存使用情况,截至目前我每天都在回收应用程序池。如果我停止回收应用程序池,内存使用量会增加。请帮我。抱歉我的英文。

public ActionResult InstagramRecentList()
{
    string filepath = Path.Combine(ConfigurationManager.AppSettings["instgramfilepath"], Constants.w_Instagram_recent_listJsonFile);

    string ClientId = ConfigurationManager.AppSettings["instgramclientid"];
    string HondaId = ConfigurationManager.AppSettings["instgramhondaid"];
    WriteInstagramRecentList(filepath, HondaId, ClientId);
    string wp = Path.Combine(ConfigurationManager.AppSettings["instgramfilepath"], Constants.r_Instagram_recent_listJsonFile);
    string Jsonstring = String.Empty;
    using (StreamReader sr = System.IO.File.OpenText(filepath))
    {
        string s = String.Empty;
        while ((s = sr.ReadLine()) != null)
        {
            Jsonstring = Jsonstring + s;
        }
    }

    TextWriter tw = new StreamWriter(wp);
    tw.WriteLine(Jsonstring);
    tw.Close();
    tw.Dispose();
    return View("UpdateResult");
}

private static void WriteInstagramRecentList(string filepath, string HondaId, string ClientId, string nextpageurl = null)
{
    string feedurl = string.Empty;
    List<object> modeldata = new List<object>();
    if (nextpageurl != null)
    {
        feedurl = nextpageurl;

        string Jsonstring = String.Empty;
        using (StreamReader sr = System.IO.File.OpenText(filepath))
        {
            string s = String.Empty;
            while ((s = sr.ReadLine()) != null)
            {
                Jsonstring = Jsonstring + s;
            }
        }
        if (!string.IsNullOrEmpty(Jsonstring))
        {
            modeldata = JsonConvert.DeserializeObject<List<object>>(Jsonstring);
        }
    }
    else
    {
        feedurl = String.Format("https://api.instagram.com/v1/users/{0}/media/recent/?client_id={1}&count={2}", HondaId, ClientId, 200);
    }

    var request = WebRequest.Create(feedurl);
    request.ContentType = "application/json; charset=utf-8";
    string text;
    var response = (HttpWebResponse)request.GetResponse();
    using (var reader = new StreamReader(response.GetResponseStream()))
    {
        text = reader.ReadToEnd();
        if (!string.IsNullOrEmpty(text))
        {
            dynamic result = System.Web.Helpers.Json.Decode(text);
            if (result.data != null)
            {
                modeldata.AddRange(result.data);
            }
            string json = JsonConvert.SerializeObject(modeldata);
            TextWriter tw = new StreamWriter(filepath);
            tw.WriteLine(json);
            tw.Close();
            tw.Dispose();
            if (result.pagination != null && !string.IsNullOrEmpty(result.pagination.next_url) && modeldata.Count < 205)
            {
                WriteInstagramRecentList(filepath, HondaId, ClientId, result.pagination.next_url);
            }

        }
    }
}

2 个答案:

答案 0 :(得分:2)

连接字符串时,不要直接使用string类。它们在C#中是不可变的(与许多其他语言一样)。这意味着您每次都要创建一个新字符串。请改用StringBuilder类,不要创建每一行的副本 - 请检查EndOfStream属性:

StringBuilder jsonString = new StringBuilder;
using (StreamReader sr = System.IO.File.OpenText(filepath))
{
    while (!sr.EndOfStream))
    {
        jsonString.AppendLine(sr.ReadLine());
    }
}

或者只使用ReadToEnd类的StreamReader方法:

String jsonString = String.Empty;
using (StreamReader sr = System.IO.File.OpenText(filepath))
{
     jsonString = sr.ReadToEnd();
}

您也可以组合使用这些方法。使用图形时应该检查的另一件事 - 你是否根据Instagram的响应创建了一些图像?如果是这样,请考虑在使用后进行处理。您也可以在using对象上使用TextWriter模式,如下所示:

using (TextWriter tw = new StreamWriter(wp))
{
    tw.WriteLine(Jsonstring);
}

总而言之,您可以重写您的方法:

using (StreamReader sr = System.IO.File.OpenText(filepath))
using (TextWriter tw = new StreamWriter(wp))
{
    tw.WriteLine(sr.ReadToEnd());
}

答案 1 :(得分:2)

我的第一个建议是 - 尽量避免递归调用 WriteInstagramRecentList方法。