请教一个资源释放、垃圾回收问题

leon51 2019-01-29 09:01:04
下面的代码很简单,就是使用Spire.Pdf给pdf文件加一个字符串:首先检查是否已加,若未加则添加字符串并将结果保存到数据库。
运行时内存会慢慢耗尽、导致程序退出。我加了Dispose()或GC.Collect()仍没有用。(问题不会出现在DBHelper,这个类一直使用没有异常的)
请问应该如何修改?谢谢!

using Spire.Pdf;
using Spire.Pdf.Graphics;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;

namespace AddWaterMark
{
class Program
{
private static readonly string connectionString = "";
private static readonly string workPath = @"";

static void Main(string[] args)
{
PdfDocument document = new PdfDocument();
string jobName;
DataRow[] rows;

string sql = "SELECT filename FROM WaterMark";
DataTable dataTable = DBHelper.ExecuteDataTable(connectionString, CommandType.Text, sql, null);
var dicFileList = GetFiles(workPath);
foreach (KeyValuePair<string, string> kv in dicFileList)
{
//如果数据库中不存在此条记录则表示未添加
rows = dataTable.Select("filename='" + kv.Key + "'");
if (rows.Length == 0)
{
try
{
jobName = kv.Key;
//添加水印
document.LoadFromFile(jobName);
if (!AddMarkSuccessed(document, jobName))
continue;

document.SaveToFile(destFile);
document.Dispose();

//添加成功后保存到数据库中
sql = $@"INSERT INTO WaterMark(filename,updatetime) VALUES ('{jobName}','{DateTime.Now}')";
DBHelper.ExecuteNonQuery(connectionString, CommandType.Text, sql, null);
}
catch (Exception)
{
}
}
}
}


private static bool AddMarkSuccessed(PdfDocument doc, string jobName)
{
try
{
float x = 160;
float y = 10;
for (int i = 0; i < doc.Pages.Count; i++)
{
//删除旧的图层
doc.Pages[i].PageLayers.DeleteOldLayer("WaterMark");
//添加新的图层
PdfFont font = new PdfFont(PdfFontFamily.TimesRoman, 30f, PdfFontStyle.Italic | PdfFontStyle.Bold);
PdfStringFormat format = new PdfStringFormat(PdfTextAlignment.Center);
PdfPageLayer layer = doc.Pages[i].PageLayers.Add("WaterMark", true);
layer.Graphics.SetTransparency(0.3f);
layer.Graphics.DrawString(jobName, font, PdfBrushes.Red, x, y, format);
}
return true;
}
catch (Exception)
{
return false;
}
}
}
}
...全文
225 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
exception92 2019-01-29
  • 打赏
  • 举报
回复
运行时内存会慢慢耗尽、导致程序退出
-》目测要看Spire.Pdf对应的文档有没有关于释放资源的说明,这个是引用的类库吧。在foreach中执行
document.SaveToFile(destFile);;之后再Dispose,下一次循环document不会出错?。或者使用类似:
using(PdfDocument document = new PdfDocument())
{
//使用document的其它操作
}
试试
xuzuning 2019-01-29
  • 打赏
  • 举报
回复
你的 document 在循环外实例化,在循环内销毁。这正常吗?
大然然 2019-01-29
  • 打赏
  • 举报
回复
document .Close() ???
leon51 2019-01-29
  • 打赏
  • 举报
回复
引用 4 楼 以专业开发人员为伍 的回复:
PdfDocument document = new PdfDocument();
放到 foreach 循环里边吧。 放到外边,你以为“速度快了”,实际上快多多少?有多大价值?你应该测试一下。反而是乱用(相对foreach语句块来说)全局变量,存在着风险。
大神就是大神,不但解决了我的问题,还知道我为什么这么做
  • 打赏
  • 举报
回复
语句
document.Dispose();
到底干什么,其实谁也不知道。只不过有人会抠字眼儿来说“释放”,但是释放了什么我相信这些人也说不出来。 其它代码也不知到哪里有所谓内存泄漏问题。 所以这个问题其实还没有任何测试基础。还是无厘头的。既然代码这么简单,那么从经验上看,最容易出错的地方就是自以为能“更快”所以滥用了(相对于 foreach 语句来说的)全局的 PdfDocument 对象。
  • 打赏
  • 举报
回复
PdfDocument document = new PdfDocument();
放到 foreach 循环里边吧。 放到外边,你以为“速度快了”,实际上快多多少?有多大价值?你应该测试一下。反而是乱用(相对foreach语句块来说)全局变量,存在着风险。

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧