excel 메모리누수

This commit is contained in:
2025-07-25 10:30:39 +09:00
parent ddb4a1c408
commit 9b94b59c49
2 changed files with 86 additions and 40 deletions

View File

@@ -1941,6 +1941,7 @@ namespace DwgExtractorManual
/// <param name="sourceFolderPath">처리할 폴더 경로</param>
private async Task ProcessFilesDwgOnly(string sourceFolderPath)
{
ExportExcel exportExcel = null;
try
{
string resultFolder = txtResultFolder.Text;
@@ -1964,29 +1965,30 @@ namespace DwgExtractorManual
LogMessage($"📂 소스 폴더: {sourceFolderPath}");
LogMessage($"💾 결과 폴더: {resultFolder}");
LogMessage("📊 Excel 내보내기 모드로 시작합니다...");
LogMessage("📝 Excel 애플리케이션을 초기화합니다...");
LogMessage("📊 Excel 내보내기 모드로 시작합니다...");
LogMessage("📝 Excel 애플리케이션을 초기화합니다...");
_exportExcel = new ExportExcel();
exportExcel = new ExportExcel();
exportExcel.ClearAccumulatedData();
// UI 응답성을 위한 양보
await Task.Yield();
// UI 응답성을 위한 양보
await Task.Yield();
// 각 DWG 파일 처리
foreach (string dwgFile in dwgFiles)
{
LogMessage($"📄 DWG 파일 처리 중: {Path.GetFileName(dwgFile)}");
_exportExcel.ExportDwgToExcel(dwgFile);
// 각 DWG 파일 처리
foreach (string dwgFile in dwgFiles)
{
LogMessage($"📄 DWG 파일 처리 중: {Path.GetFileName(dwgFile)}");
exportExcel.ExportDwgToExcel(dwgFile);
// UI 응답성을 위한 양보
await Task.Yield();
}
// UI 응답성을 위한 양보
await Task.Yield();
}
// DWG 전용 워크북 저장
LogMessage("💾 DWG 전용 Excel 파일 저장 중...");
_exportExcel.SaveDwgOnlyMappingWorkbook(resultFolder);
// DWG 전용 워크북 저장
LogMessage("💾 DWG 전용 Excel 파일 저장 중...");
exportExcel.SaveDwgOnlyMappingWorkbook(resultFolder);
LogMessage("✅ DWG 전용 Excel 파일 저장 완료");
LogMessage("✅ DWG 전용 Excel 파일 저장 완료");
}
catch (Exception ex)
{
@@ -1995,8 +1997,8 @@ namespace DwgExtractorManual
}
finally
{
_exportExcel?.Dispose();
_exportExcel = null;
exportExcel?.Dispose();
exportExcel = null;
}
}

View File

@@ -476,12 +476,17 @@ namespace DwgExtractorManual.Models
try
{
mappingSheet.Cells[currentRow, 1] = fileName; // FileName
mappingSheet.Cells[currentRow, 2] = mapKey; // MapKey
mappingSheet.Cells[currentRow, 3] = aiLabel ?? ""; // AILabel
mappingSheet.Cells[currentRow, 4] = dwgTag ?? ""; // DwgTag
mappingSheet.Cells[currentRow, 5] = attValue ?? ""; // DwgValue (Att_value)
mappingSheet.Cells[currentRow, 6] = pdfValue ?? ""; // PdfValue (Pdf_value)
// 배치 업데이트를 위한 배열 사용
object[,] rowData = new object[1, 6];
rowData[0, 0] = fileName; // FileName
rowData[0, 1] = mapKey; // MapKey
rowData[0, 2] = aiLabel ?? ""; // AILabel
rowData[0, 3] = dwgTag ?? ""; // DwgTag
rowData[0, 4] = attValue ?? ""; // DwgValue (Att_value)
rowData[0, 5] = pdfValue ?? ""; // PdfValue (Pdf_value)
Excel.Range range = mappingSheet.Range[mappingSheet.Cells[currentRow, 1], mappingSheet.Cells[currentRow, 6]];
range.Value = rowData;
Debug.WriteLine($"[DEBUG] Row {currentRow} written successfully");
}
@@ -880,24 +885,36 @@ namespace DwgExtractorManual.Models
headerRange.Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightGray);
headerRange.Borders.LineStyle = Excel.XlLineStyle.xlContinuous;
// 데이터 입력
int row = 2;
foreach (var fileEntry in FileToMapkeyToLabelTagValuePdf)
// 데이터 입력 (배치 처리로 성능 향상)
int totalRows = FileToMapkeyToLabelTagValuePdf.Sum(f => f.Value.Count);
if (totalRows > 0)
{
string fileName = fileEntry.Key;
foreach (var mapEntry in fileEntry.Value)
object[,] data = new object[totalRows, 5];
int row = 0;
foreach (var fileEntry in FileToMapkeyToLabelTagValuePdf)
{
string mapKey = mapEntry.Key;
var (aiLabel, dwgTag, dwgValue, pdfValue) = mapEntry.Value;
string fileName = fileEntry.Key;
foreach (var mapEntry in fileEntry.Value)
{
string mapKey = mapEntry.Key;
var (aiLabel, dwgTag, dwgValue, pdfValue) = mapEntry.Value;
dwgOnlyWorksheet.Cells[row, 1] = fileName;
dwgOnlyWorksheet.Cells[row, 2] = mapKey;
dwgOnlyWorksheet.Cells[row, 3] = aiLabel;
dwgOnlyWorksheet.Cells[row, 4] = dwgTag;
dwgOnlyWorksheet.Cells[row, 5] = dwgValue;
data[row, 0] = fileName;
data[row, 1] = mapKey;
data[row, 2] = aiLabel;
data[row, 3] = dwgTag;
data[row, 4] = dwgValue;
row++;
row++;
}
}
// 한 번에 모든 데이터 입력
Excel.Range dataRange = dwgOnlyWorksheet.Range[
dwgOnlyWorksheet.Cells[2, 1],
dwgOnlyWorksheet.Cells[totalRows + 1, 5]];
dataRange.Value = data;
}
// 컬럼 자동 크기 조정
@@ -918,8 +935,12 @@ namespace DwgExtractorManual.Models
// 워크북 정리
dwgOnlyWorkbook.Close(false);
System.Runtime.InteropServices.Marshal.ReleaseComObject(dwgOnlyWorksheet);
System.Runtime.InteropServices.Marshal.ReleaseComObject(dwgOnlyWorkbook);
ReleaseComObject(dwgOnlyWorksheet);
ReleaseComObject(dwgOnlyWorkbook);
// 가비지 컬렉션 강제 실행으로 메모리 해제
GC.Collect();
GC.WaitForPendingFinalizers();
}
catch (System.Exception ex)
{
@@ -1372,6 +1393,29 @@ namespace DwgExtractorManual.Models
}
}
/// <summary>
/// 폴더 간 처리를 위해 누적된 데이터를 정리합니다.
/// </summary>
public void ClearAccumulatedData()
{
try
{
Debug.WriteLine("[DEBUG] 누적 데이터 정리 시작");
FileToMapkeyToLabelTagValuePdf.Clear();
titleBlockCurrentRow = 2;
textEntitiesCurrentRow = 2;
mappingDataCurrentRow = 2;
Debug.WriteLine("✅ 누적 데이터 정리 완료");
}
catch (System.Exception ex)
{
Debug.WriteLine($"❌ 누적 데이터 정리 중 오류: {ex.Message}");
}
}
/// <summary>
/// JSON 내용을 정리하여 파싱 가능한 상태로 만듭니다.
/// 주석 제거 및 기타 무효한 문자 처리