我正在使用ZedGraph库,但是在网站而不是Web窗体应用程序上。快速介绍 - 应用程序从数据库获取数据,生成图形,将其保存为图像,然后在网页上显示图像。
我有一个GraphController类,基本上看起来像这样:
public class GraphController {
private static GraphController instance;
private static ZedGraph.ZedGraphControl graph;
protected GraphController() { }
public static GraphController Instance {
get {
if (instance == null){
instance = new GraphController();
}
return instance;
}
}
public string GenerateGraph(Dictionary<DateTime, float> graphData, DataRow details, string graphType) {
if ((graph == null) || (graph.IsDisposed == false)) {
graph = new ZedGraph.ZedGraphControl();
}
graph.GraphPane.Title.IsVisible = false;
// function calls to generate graph. Graph object is referenced in these.
return SaveGraphAsImage(0000, graphType);
}
private void AddGridLines() {
// example of graph reference
graph.GraphPane.XAxis.MajorGrid.IsVisible = true;
}
private string SaveGraphAsImage(string paramId, string graphType) {
// Should deal with save location here
string location = HttpRuntime.AppDomainAppPath + "Graphs\\" + DateTime.Now.ToString("dd-MM-yyyy");
string filename = DateTime.Now.ToString("dd-MM-yyyy-HH-mm-ss-") + graphType + "-" + paramId + ".png";
if(System.IO.Directory.Exists(location) == false){
System.IO.Directory.CreateDirectory(location);
}
graph.Refresh();
try {
using (graph) {
string outputFileName = location + "\\" + filename;
if (File.Exists(outputFileName) == false) {
Bitmap image = graph.GraphPane.GetImage(960, 660, 180);
image.Save(outputFileName, ImageFormat.Png);
image.Dispose();
}
}
graph = null; // double check that it is removed.
return "../Graphs/" + DateTime.Now.ToString("dd-MM-yyyy") + "/" + filename;
}
catch (Exception ex) {
log("An error occured generating a graph. \n\n Error message: \n " + ex.Message + " \n\n Stack trace: \n " + ex.StackTrace);
graph = null;
return "#";
}
}
}
我尽可能地减少了它,但它应该显示如何创建,使用和删除ZedGraph对象。
我已经尝试过一些内存增强功能,尽可能地删除图形对象,并尝试using(){}
进程以希望自动删除它,但欢迎进一步的建议。
我的目标是改善内存管理并减少这些错误。运行本地性能测试,我收到了很多Control 'ZedGraphControl' accessed from a thread other than the thread it was created on.
错误。我对线程相对较新,所以我不确定a)它是否是这里需要的东西,或者b)可以做一些事情来禁用这种可能性,或者更好地管理图形对象以确保它总是在同一个线程中?
修改:首先从.aspx.cs页面调用此GraphController
,其中包含以下内容:GraphController.GraphController.Instance.GenerateGraph(data, details, "graph-type");
第二次编辑:我重新编写了代码,没有将ZedGraphControl作为private static
,而是在GenerateGraph
内创建,然后在必要时传递。在60秒内对多达1,000个用户进行测试看起来已经消除了跨线程问题 - 这听起来有可能吗?
答案 0 :(得分:0)
这里的问题是使用ZedGraph
个变量。正如Henk Holterman在评论中指出的那样,只要应用程序进程处于活动状态,静态变量就会保持活动状态,并且与任何/所有用户请求分开。因此,通过将static
对象作为ZedGraph
变量,它意味着它可能仍然可用于多个请求,而不会被正确清除,遇到内存和跨线程问题。
解决方案是在第一个GenerateGraph
函数中声明class Solution {
public int solution(int A, int B, int K) {
return (B==0) ? 1 : B/K + ( (A==0) ? 1 : (-1)*(A-1)/K);
}
}
实例,然后将相同的对象传递给使用它的每个其他函数。这可以确保它是整个过程中访问的同一线程中的同一对象。