В вашем коде вы имеете дело с довольно низкоуровневым API. Хотя ваша задача довольно проста, и низкоуровневый API все еще здесь достаточен, с высокоуровневым API макета вы можете достичь цели намного быстрее.
Для начала вы можете повторно использовать свой код, чтобы создать PdfDocument
и определить URL-адрес для изображения SVG:
PdfDocument doc = new PdfDocument(new PdfWriter(new FileOutputStream(new File("D:\\test.pdf")),
new WriterProperties().setCompressionLevel(0)));
String svgPath = "...svgPathHere";
Затем, вместо немедленного рисования изображения SVG на странице, вы можно преобразовать его в объект Image
из API layout
, который вы можете настроить: масштабировать для соответствия определенным размерам, установить фиксированное положение (левая нижняя точка) и т. д .:
Image image = SvgConverter.convertToImage(new FileInputStream(svgPath), doc);
image.setFixedPosition(100, 200);
image.scaleToFit(300, 300);
Чтобы связать все вместе , создайте объект высокого уровня Document
и добавьте туда свое изображение. Не забудьте закрыть Document
экземпляр. Вам больше не нужно закрывать оригинал PdfDocument
:
Document layoutDoc = new Document(doc);
layoutDoc.add(image);
layoutDoc.close();
Я склонен использовать ключевое слово "использования", особенно при контакте с открытием и заключительными соединениями с базой данных. "использование" является ярлыком на Расположить шаблон - вот ссылка на рецензию MSDN и здесь является ссылкой на полезную запись в блоге с обзором.
Мое понимание - это с SqlDataSource
, управление соединениями выполняется для Вас, и у Вас нет ничего для боязни.
ObjectDataSource
не говорит с базой данных непосредственно во-первых, таким образом, это будет безопасно - пока основной объект выполняет свое соединение и управление читателя правильно.
Поскольку другие упомянули, Close()
и using
Ваши друзья для классов, с которыми Вы используете ObjectDataSource
.
Моя догадка - то, что при вычищении кодовой базы эффективно Вы, вероятно, уничтожили проблему.
Я соглашаюсь, что для ObjectDataSource закрытие должно быть обработано его Избранным методом. Мой метод Выбора ObjectDataSource возвращает SqlDataReader. Мое беспокойство... будет SqlDataReader быть представленным бесполезным при закрытии после возврата его к UI. например, см. следующий пример кода. Я не попробовал его и не хочу делать это на этой стадии развития.
SqlDataReader MySelectMethod(){
SqlDataReader dr = null;
try{
dr = DBObject.GetDataReader();
return dr;
}
finally{
dr.Close();
}
}
Спасибо за все исходные данные, полученные до сих пор!
...........
Мое понимание - то, что с SqlDataSource, управление соединениями выполняется для Вас, и у Вас нет ничего для боязни.
ObjectDataSource не говорит с базой данных непосредственно во-первых, таким образом, это будет безопасно - пока основной объект выполняет свое соединение и управление читателя правильно.
Как другие упомянули, Близко () и использование Ваши друзья для классов, которые Вы используете с ObjectDataSource
.
Вызов.Dispose () должен обработать, моются и высвобождают любые сохраненные средства, но.Close () метод должен становиться названным также, когда объект сделан, читая от читателя.
Я полагаю, что SqlDataSource обработает свои собственные проблемы соединения/читателя, таким образом, никакие заботы там. Что касается Ваших ручных соединений, я нашел этот шаблон полезным в прошлом:
using (SqlConnection connection = new SqlConnection(connectionString))
{
try
{
SqlCommand command = connection.CreateCommand();
command.CommandText = ...
connection.Open();
using (SqlDataReader reader = command.ExecuteReader())
{
do
{
while (reader.Read())
{
... handle each row ...
}
} while (reader.NextResult());
}
}
catch (Exception ex)
{
... error handling ...
}
finally
{
if (connection != null && connection.State == ConnectionState.Open)
{
connection.Close();
}
}
}
Чтобы повысить производительность Close () / Dispose (), рассмотрите возможность вызова Cancel () для связанного объекта команды перед удалением или закрытием средства чтения, особенно если вы не достигли конца записи set.
Например:
using (var cmd = ... ))
{
using (var reader = (DbDataReader) cmd.ExecuteReader())
{
try
{
ConsumeData(reader); // may throw
}
catch(Exception)
{
cmd.Cancel();
throw;
}
}
}