เวลาออกรายงานบน Excel ผมมักจะเขียนโค้ดประมาณนี้ครับ (ใช้ BackgroundWorker ด้วย)
Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Dim wk As BackgroundWorker = DirectCast(sender, BackgroundWorker)
Try
isSuccess = False
CreateExcel(wk, e)
CreateReportByLocation(wk, e)
CreateReportByTitle(wk, e)
CreateReportList(wk, e)
isSuccess = True
Catch ex As Exception
isSuccess = False
Finally
FinishCreatingReport(wk, e)
End Try
End Sub
คำสั่ง CreateExcel จะเป็นการ New Excel.Application รวมถึงสร้าง WorkBook สำหรับเริ่มต้นการออกรายงาน
ส่วน CreatReportXXX จะเป็นการสร้างรายงานแต่ละ WorkSheet ตามต้องการครับ สุดท้ายก็ FinishCreatingReport จะเป็นการคืน memory ให้กับระบบ เราจะมาลองดู function นี้กันครับ
Private Sub FinishCreatingReport(ByVal wk As BackgroundWorker, ByRef e As DoWorkEventArgs)
Try
xlBook.SaveAs(fileName)
Catch ex As Exception
MessageBox.Show(ex.Message & vbCrLf & "Please contact ITD.", My.Application.Info.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
Finally
'// Release memory
wk.ReportProgress(95)
xlApp.Quit()
GC.SuppressFinalize(xlSheet)
GC.SuppressFinalize(xlBook)
GC.SuppressFinalize(xlApp)
GC.Collect()
xlSheet = Nothing
xlBook = Nothing
xlApp = Nothing
End Try
End Sub
พอรันโปรแกรมและเปิด Task Manager ดูพบว่า
1. พอ BackgroundWorker1_RunWorkerCompleted ทำงานเสร็จ (แน่นอนว่า เรียก FinishCreatingReport ซึ่งอยู่ใน BackgroundWorker1_DoWork แล้ว) ใน Task Manager ยังมี Excel.exe ค้างอยู่ครับ
2. ถ้ากดปุ่มเพื่อสั่งออกรายงานใหม่อีกครั้ง Excel.exe จะหายไปจาก Task Manager พอโปรแกรมสั่ง CreateExcel ถึงจะสร้างขึ้นมาใหม่
3. เมื่อ BackgroundWorker ทำงานเสร็จ ออกรายงานเรียบร้อย Excel.exe ยังคงอยู่ ถ้าผมปิด form นี้ Excel.exe จะหายไปจาก Task Manager แต่ถ้าผม stop debugging ใน Visual Studio หรือโปรแกรมที่เขียนมี bug และ shutdown ไป Excel.exe จะยังคงค้างอยู่ใน Task Manager
ทีนี้ผมลองเพิ่มคำสั่ง ReleaseComObject ครับ
Private Sub FinishCreatingReport(ByVal wk As BackgroundWorker, ByRef e As DoWorkEventArgs)
Try
xlBook.SaveAs(fileName)
Catch ex As Exception
MessageBox.Show(ex.Message & vbCrLf & "Please contact ITD.", My.Application.Info.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
Finally
'// Release memory
wk.ReportProgress(95)
xlApp.Quit()
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheet)
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBook)
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp)
GC.SuppressFinalize(xlSheet)
GC.SuppressFinalize(xlBook)
GC.SuppressFinalize(xlApp)
GC.Collect()
xlSheet = Nothing
xlBook = Nothing
xlApp = Nothing
End Try
End Sub
ลองรันโปรแกรมดู พบว่าเมื่อ BackgroundWorker ทำงานเสร็จ Excel.exe จะถูกลบทิ้งไปทันที ไม่เหลือใน Task Manager แล้ว (พอไล่ดูอย่างละเอียด พบว่า Excel.exe จะหายไป ก่อน BackgroundWorker1_RunWorkerCompleted จะทำงานเสร็จครับ)
ดังนั้นนอกจากจะใช้งาน Excel แล้ว ถ้าเรามีการทำ COM Marshal (InterOp) กรุณาเรียกใช้ System.Runtime.InteropServices.Marshal.ReleaseComObject เพื่อจะได้มั่นใจว่า Unmanaged Memory ได้ถูก Release จริงๆครับ
ไม่มีความคิดเห็น:
แสดงความคิดเห็น