显示实时数据时内存不断增加

时间:2019-05-06 08:11:28

标签: asp.net-mvc entity-framework memory signalr

我正在使用mvc应用程序来显示实时数据(使用IIS服务器),我必须使用EF和signalR(这是我对这两者的新手),该软件可以完美运行,除了其中一部分我必须每秒钟(无论何时修改数据库)都从SQL Server重新加载数据,最多可以修改70行(但通常约40行)。
它可以工作,但是当我检查IIS worker进程时,无论我尝试什么,即使不释放它,内存使用量也一直在增长。它使用JS重新加载了这部分,而且似乎是问题所在(甚至对我来说也是这样)似乎不是正确的方法),但我找不到其他方法。
我已经尝试过强制连接/断开连接,GC似乎已经完成了他的工作,我知道我可以使用IIS服务器来回收池应用程序并限制内存使用量,但这不能解决问题。我知道问题来自部分视图上的重新加载,但是我被阻止了。
希望大家能帮忙。

模型 (该模型非常基本,仅需进行一些计算)

public decimal TRS_EQ
        {
            get 
            {
                if (pcs_theoriques_eq != " " && pcs_theoriques_eq != "" && pcs_theoriques_eq != null)
                {
                    long theoEq = Convert.ToInt64(pcs_theoriques_eq);
                    if (pcs_bonnes_eq != null && pcs_bonnes_eq != " " && pcs_bonnes_eq != "" && theoEq != 0)
                    {
                        return Convert.ToDecimal(pcs_bonnes_eq) / theoEq * 100;
                    }
                }
                return 0.0m;
            }
        }

控制器

private IQueryable<TempsReel> collection;
public ActionResult IndexPartial()
        {
            Response.Cache.SetNoStore();
            Response.Cache.SetNoServerCaching();
            using (var db = new SignalRTestContext())
            {
                collection = from g in db.TempsReels select g;
                collection = collection.OrderBy(g => g.groupe_machine);
                ViewBag.NotifierEntity = db.GetNotifierEntity<TempsReel>(collection).ToJson();
                ViewBag.IdMachine = Variables.idMachine;
                ViewBag.Count = Variables.ListCatArrets.Count();
                ViewBag.NomCategorie = Variables.ListCatArrets.Select(c => c.arretcatName).ToList();
                ViewBag.Color = Variables.ListCatArrets.Select(c => c.arretcatColor).ToList();
                collection = ArretTempsReel.OrganiseListParGroupe(collection);
                GC.Collect();
                db.Dispose();
                return PartialView(collection.ToList());
            }               
        }

视图(仅重新加载部分视图)

<div id="tbTempsReelMachines">   
    @{ Html.RenderPartial("IndexPartial", Model); }
</div>

@section scripts 
{
    <script src="~/Scripts/jquery.signalR-2.4.0.min.js"></script>
    <script src="~/signalr/hubs"></script>
    <script type="text/javascript">
        var signalRHubInitialized = false;
        $(function ()
        {
            InitializeSignalRHubStore();
        });

        function InitializeSignalRHubStore()
        {
            if (signalRHubInitialized)
                return;
            try
            {
                var clientHub = $.connection.tempsReelArretHub;

                clientHub.client.broadcastMessage = function (message)
                {
                    if (message === "Refresh")
                    {
                        ReloadIndexPartial();
                    }                  
                };
                $.connection.hub.start().done(function ()
                {
                    clientHub.server.initialize($("#NotifierEntity").val());
                    signalRHubInitialized = true;
                });

            } catch (err) {
                signalRHubInitialized = false;
            }
        };

        function ReloadIndexPartial()
        {

            $.post('@(Url.Action("IndexPartial",
            "TempsReels", null, Request.Url.Scheme))')
                .done(function (response)
                {
                    $("#tbTempsReelMachines").html(response)     
                    if (!signalRHubInitialized)
                        InitializeSignalRHubStore();     
                });
            $("#tbTempsReelMachines").end();
        };
    </script>
}

ViewModel(用于组织数据)

public class ArretTempsReel
    {
        public static IQueryable<TempsReel> OrganiseListParGroupe(IQueryable<TempsReel> InputList)
        {
            List<string> Groupe = InputList.Select(g => g.groupe_machine).Distinct().ToList();
            List<TempsReel> L = new List<TempsReel>();
            foreach (var item in Groupe)
            {
                var l = InputList.Where(f => f.groupe_machine == item).ToList();
                L.AddRange(l);
                TempsReel SP = new TempsReel();
                SP = SommePartielle(l);
                L.Add(SP);
            }
            return L.AsQueryable<TempsReel>();
        }
        public static TempsReel SommePartielle(List<TempsReel> InputList)
        {
            TempsReelClone TC = new TempsReelClone();
            try
            {
                foreach (var item in InputList)
                {
                    TC.pcs_bonnes_eq += (item.pcs_bonnes_eq != null) ? Convert.ToInt64(item.pcs_bonnes_eq) : 0;
                    TC.pcs_bonnes_j += (item.pcs_bonnes_j != null) ? Convert.ToInt64(item.pcs_bonnes_j) : 0;
                    TC.pcs_bonnes_of += (item.pcs_bonnes_of != null) ? Convert.ToInt64(item.pcs_bonnes_of) : 0;
                    TC.pcs_mauvaises_eq += (item.pcs_mauvaises_eq != null) ? Convert.ToInt64(item.pcs_mauvaises_eq) : 0;
                    TC.pcs_mauvaises_j += (item.pcs_mauvaises_j != null) ? Convert.ToInt64(item.pcs_mauvaises_j) : 0;
                    TC.pcs_mauvaises_of += (item.pcs_mauvaises_of != null) ? Convert.ToInt64(item.pcs_mauvaises_of) : 0;
                    TC.pcs_theoriques_eq += (item.pcs_theoriques_eq != null) ? Convert.ToInt64(item.pcs_theoriques_eq) : 0;
                    TC.pcs_theoriques_j += (item.pcs_theoriques_j != null) ? Convert.ToInt64(item.pcs_theoriques_j) : 0;
                    TC.pcs_theoriques_of += (item.pcs_theoriques_of != null) ? Convert.ToInt64(item.pcs_theoriques_of) : 0;
                }
                return new TempsReel
                {
                    pcs_bonnes_eq = TC.pcs_bonnes_eq.ToString(),
                    pcs_bonnes_j = TC.pcs_bonnes_j.ToString(),
                    pcs_bonnes_of = TC.pcs_bonnes_of.ToString(),
                    pcs_mauvaises_eq = TC.pcs_mauvaises_eq.ToString(),
                    pcs_mauvaises_j = TC.pcs_mauvaises_j.ToString(),
                    pcs_mauvaises_of = TC.pcs_mauvaises_of.ToString(),
                    pcs_theoriques_eq = TC.pcs_theoriques_eq.ToString(),
                    pcs_theoriques_j = TC.pcs_theoriques_j.ToString(),
                    pcs_theoriques_of = TC.pcs_theoriques_of.ToString(),
                    nom_machine = "TOTAL GROUPE",
                    categorie = "",
                    nom_arret = ""

                };
            }
            catch (Exception)
            {
                return null;
            }
        }

集线器

public class TempsReelHub : Hub
    {
        internal NotifierEntity NotifierEntity { get; private set; }

        public void DispatchToClient()
        {
            Clients.All.broadcastMessage("Refresh");
        }

        public void Initialize(String value)
        {
            NotifierEntity = NotifierEntity.FromJson(value);
            if (NotifierEntity == null)
                return;
            Action<String> dispatcher = (t) => { DispatchToClient(); };
            PushSqlDependency.Instance(NotifierEntity, dispatcher);
        }
    }

SQL更改通知者

public class SqlDependencyRegister
    {
        public event SqlNotificationEventHandler SqlNotification;

        readonly NotifierEntity notificationEntity;

        internal SqlDependencyRegister(NotifierEntity notificationEntity)
        {
            this.notificationEntity = notificationEntity;
            RegisterForNotifications();
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security",
        "CA2100:Review SQL queries for security vulnerabilities")]
        void RegisterForNotifications()
        {
            using (var sqlConnection = new SqlConnection(notificationEntity.SqlConnectionString))
            {
                using (var sqlCommand = new SqlCommand(notificationEntity.SqlQuery, sqlConnection))
                {
                    foreach (var sqlParameter in notificationEntity.SqlParameters)
                        sqlCommand.Parameters.Add(sqlParameter);
                    sqlCommand.Notification = null;
                    var sqlDependency = new SqlDependency(sqlCommand);
                    sqlDependency.OnChange += OnSqlDependencyChange;
                    if (sqlConnection.State == ConnectionState.Closed)
                    {
                        sqlConnection.Open();
                    }
                    sqlCommand.ExecuteNonQuery();
                    //sqlCommand.Parameters.Clear();
                    sqlConnection.Close();
                }
            }
        }
        void OnSqlDependencyChange(object sender, SqlNotificationEventArgs e)
        {
            SqlNotification?.Invoke(sender, e);
            RegisterForNotifications();
        }
    }

0 个答案:

没有答案