저는 멀티 스레딩을 시작했습니다. 내 멀티 스레드 코드의 테스트를 실행하고 있지만 OutOfMemory 예외가 발생했습니다.OutOfMemory 예외 스레딩 받기
코드가 PS를 새로운 스레드를 사용하여 PDF로 변환 중입니다. 작업은 약 0.5 초 정도 걸리므로이 테스트에서는 주 스레드를 잠자 게 잠깐 만져서 너무 많은 작업이 실행되지 않도록합니다. 그것은 OutOfMemory 예외를 던지기 전에 900을 넘었습니다.
스레드 풀, 세마포 또는 작업 병렬을 사용하여 스레드를 제한해야한다는 것을 알고 있지만 지금은 스레드 테스트를하고 있습니다.
Dim sr As New StreamReader(PSTempFolder & "PDFWrite.txt")
Do While Not sr.EndOfStream
'get PS
Dim FileNamePS As String = sr.ReadLine
'get folder
Dim CustFolder As IO.DirectoryInfo
CustFolder = GetCustFolder(FileNamePS)
'set PDF path and name
FileNamePDF = CustFolder.FullName & "\Statement.pdf"
Dim t As Thread
Dim n As ConvertPDF = Nothing
n = New ConvertPDF
n.DeletePS = False
n.PSFileName = FileNamePS
n.PDFFileName = FileNamePDF
t = New Thread(AddressOf n.callConvertToPDF)
t.Start()
'wait
Thread.Sleep (1000)
Loop
sr.Close()
너무 많은 스레드를 생성하고 이전 스레드를 정리하지 않아야합니다. 새 스레드를 작성하기 전에 스레드를 정리/처리하려면 어떻게합니까?
두 번째 해결 방법 (이 컨텍스트에서)은 단순히 동일한 스레드를 사용한다고 가정합니다.하지만이 질문에 대해서는 스레드 폐기와 메모리 해제에 더 관심이 있습니다. 어떻게해야합니까?
Class ConvertPDF
Public PSFileName As String
Public PDFFileName As String
Public DeletePS As Boolean = False
Delegate Function ConvertToPDFdel(ByVal svPsFileName As String, _
ByVal svPDFName As String, _
ByVal DeletePS As Boolean) As Integer
Sub callConvertToPDF()
Dim dlgt As New ConvertToPDFdel(AddressOf ConvertToPDF)
Dim i As Integer = dlgt.Invoke(PSFileName, PDFFileName, DeletePS)
End Sub
End Class
Public Function ConvertToPDF(ByVal svPsFileName As String, _
ByVal svPDFName As String, _
ByVal DeletePS As Boolean) As Integer
'check for file
If Not IO.File.Exists(svPsFileName) Then
Throw New ApplicationException(svPsFileName & " cannot be found")
End If
'delete old file
If IO.File.Exists(svPDFName) Then IO.File.Delete(svPDFName)
'convert
Dim myProcInfo As New ProcessStartInfo
myProcInfo.FileName = DanBSolutionsLocation & "Misc\GhostScript\GSWIN32C.EXE"
myProcInfo.Arguments = "-sDEVICE=pdfwrite -q -dSAFER -dNOPAUSE -sOUTPUTFILE=""" & svPDFName & """ -dBATCH """ & svPsFileName & """"
'Debug.Print(myProcInfo.Arguments)
'do the conversion
Dim myProc As Process = Process.Start(myProcInfo)
'wait for finish (no more than 20 seconds)
myProc.WaitForExit(20000)
myProcInfo = Nothing
myProc.Dispose()
'delete PS
If DeletePS Then
If IO.File.Exists(svPDFName) Then IO.File.Delete(svPsFileName)
End If
End Function
편집 : 여기
코드의 나머지 부분입니다 내가 GroverBoy의 코드와 내 결과가 확정적이지 사이에 더 많은 테스트를했다. 가끔은 다른 쪽이 때때로 더 좋습니다. 어쩌면이 둘은 정말로 같고 그 문제는 다른 곳에서도있을 수 있습니다.새 스레드가 완료되는 데 0.55 초가 걸리는 새 프로세스가 시작됩니다. 메인 쓰레드가 매 반복마다 1 초를 기다린다면, 한번에 하나 이상의 쓰레드 나 하나의 열린 파일을 가질 수 없다는 것을 의미합니다. 왜 이것이 사실이 아닌가?
실제로 일어나는 일은 다양하며 그 이유는 확실하지 않습니다. 나는 메인 루프에서 100 초의 루프와 1 초의 대기를 테스트하고있다. 필자는 일반적으로 작업 관리자의 성능 탭을 봅니다. 때로는 코드를 실행하고 스레드 수는 2 ~ 6 여분으로 변동하고 커밋 요금은 1044M에서 1150M 사이에서 변동합니다. 이것이 내가 원하는거야.
다른 경우 동일한 코드 (100 회 반복)를 실행하고 스레드 수가 63 개를 초과하여 계속 증가합니다. 그리고 Commit Charge는 1044M에서 1272M 이상으로 계속 증가합니다.
프로그램이 스레드를 일관되게 정리할 수 있도록하려면 어떻게해야합니까?
'callConvertToPDF'가 완료되면 새 스레드가 종료되고 정리됩니다. 'callConvertToPDF' 안에서 스트림을 풀어 주나요? PS 또는 PDF 파일은 변환이 완료된 후에도 열린 상태로 유지됩니다. – kennyzx
@kennyzx 귀하의 의견을 보내 주셔서 감사합니다. 호기심에 대비하여 나머지 코드를 게시했지만 GroverBoy의 대답이 그 차이를 만들었습니다. 감사. –
이 코드를 올바르게 이해하면 900 개 이상의 파일 이름을 읽었으며 각 파일에 대해 새 스레드와 새 프로세스를 모두 시작합니다. 그 맞습니까? – Enigmativity