我正在使用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();
}
}