简体   繁体   中英

C# Memory management (Memory leak?)

I am working on a program in WPF that basically retrieves JSON data from a WEB API and parses it then saves it to database with EF.

The problem is the memory usage of the program keeps on increasing as the time goes by. (From 20MB to 2gigs).

The following is the code that I am using.

Is there any optimization i can perform to keep the memory under a limit and say the unused objects gets deleted periodically.

void getMatchInfo_Work(object sender, DoWorkEventArgs e)
    {
        HttpClient client = new HttpClient();
        DataConnection dc = new DataConnection();
        dc.Configuration.AutoDetectChangesEnabled = false;
        dc.Configuration.ValidateOnSaveEnabled = false;



       do{
        do
        {
            using (Stream s = client.GetStreamAsync("http://api.steampowered.com/IDOTA2Match_570/GetMatchHistoryBySequenceNum" +
                "/v1/?key="+devkey+"&start_at_match_seq_num=" + matchseq.ToString()).Result)
            using (StreamReader sr = new StreamReader(s))
            using (JsonReader reader = new JsonTextReader(sr))
            {

                JsonSerializer serializer = new JsonSerializer();
                MatchMain match;
                MatchDesc player;
                RootElement matchSeq = serializer.Deserialize<RootElement>(reader);
                if (matchSeq.result.status == 1)
                {

                    foreach (var m in matchSeq.result.matches)
                    {


                         match = new MatchMain();
                        match.MatchID = m.match_id;
                        match.Win = m.radiant_win;
                        match.Duration = m.duration;


                        match.StartTime = ConvertFromUnixTimestamp(m.start_time);
                        match.TimeStamp = m.start_time;
                        match.SeqNo = m.match_seq_num;
                        matchseq = m.match_seq_num + 1;
                        match.RadTower = m.tower_status_radiant;
                        match.DireTower = m.tower_status_dire;
                        match.RadRax = m.barracks_status_radiant;
                        match.DireRax = m.barracks_status_dire;
                        match.cluster = m.cluster;
                        match.FBTime = m.first_blood_time;
                        match.LobbyType = m.lobby_type;
                        match.HumanCount = m.human_players;
                        match.LeagueID = m.leagueid;
                        match.GameMode = m.game_mode;

                        dc.MatchMain.Add(match);


                        count++;
                        foreach (var p in m.players)
                        {
                             player = new MatchDesc();
                            player.MatchID = m.match_id;
                            player.AccountID = p.account_id;
                            player.PlayerSlot = p.player_slot;
                            player.HeroID = p.hero_id;
                            player.First = p.item_0;
                            player.Second = p.item_1;
                            player.Third = p.item_2;
                            player.Fourth = p.item_3;
                            player.Fifth = p.item_4;
                            player.Sixth = p.item_5;
                            player.Kills = p.kills;
                            player.Deaths = p.deaths;
                            player.Assists = p.assists;
                            player.LeaverStatus = p.leaver_status;
                            player.Gold = p.gold;
                            player.LastHits = p.last_hits;
                            player.Denies = p.denies;
                            player.GPM = p.gold_per_min;
                            player.XPM = p.xp_per_min;
                            player.GoldSpent = p.gold_spent;
                            player.HeroDamage = p.hero_damage;
                            player.TowerDamage = p.tower_damage;
                            player.Healing = p.hero_healing;
                            player.HeroLevel = p.level;

                            dc.MatchDesc.Add(player);



                        }
                        getMatchInfo.ReportProgress(1);
                    }

                    dc.SaveChanges();


                }

                else
                {
                    result = 0;
                }
            }

        } while (result == 1);
        Thread.Sleep(60000);
       }while( result>-999);


    }


void getMatchInfo_Progress(object sender, ProgressChangedEventArgs e)
    {
        if (result != 0)
        {
            txtProgress.Text = count + " matches updated in database and continuing.";

        }
        else
        {
            txtProgress.Text = count + " matches updated in database and waiting for API.";
        }
        txtTime.Text =sw.Elapsed.Hours.ToString()+" hours "+ sw.Elapsed.Minutes.ToString()+" minutes "+
            sw.Elapsed.Seconds.ToString()+" seconds";
    }

Edit: Button click code

  private void btnRetrieveData_Click(object sender, RoutedEventArgs e)
    {



        getMatchInfo.DoWork += new DoWorkEventHandler(getMatchInfo_Work);

        getMatchInfo.ProgressChanged += new ProgressChangedEventHandler(getMatchInfo_Progress);
        getMatchInfo.WorkerReportsProgress = true;
        txtProgress.Text = "Process started";
        matchseq = Convert.ToInt64(txtSeqNo.Text);
        devkey = txtKey.Text;
        sw.Start();
        getMatchInfo.RunWorkerAsync();

    }

DataConnection context keeps tracking all objects that it ever saw. Put creation of dc inside the loop and dispose it every time. You don't need the context after each SaveChanges is called.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM