Я только начинаю с многопоточности. Я выполняю проверку моего многопоточного кода, но получаю исключение OutOfMemory.Получение потока исключения OutOfMemory
Код преобразует PS в PDF с использованием новой темы. Задача занимает около полутора секунд, поэтому для этого теста я просто сплю главный поток на секунду, чтобы убедиться, что у меня не слишком много задач. Он сделал более 900, прежде чем выбросить исключение OutOfMemory.
Я знаю, что мне нужно использовать пул потоков, семафор или задачу. Параллельно ограничить мои потоки, но пока я просто проверяю свои темы.
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
EDIT: Я сделал еще несколько тестов между кодом и моим GroverBoy и результаты не являются окончательными. Иногда лучше иногда другой. Возможно, эти два на самом деле одинаковы, и проблема в другом месте.
Новый поток запускает новый процесс, который занимает 0,55 секунды. Если основной поток ожидает 1 секунду каждой итерации, это должно означать, что у нас никогда не будет более одного потока или одного открытого файла за раз. Почему это не так?
Что на самом деле происходит, будет отличаться, и я не знаю, почему. Я тестирую с циклом 100 и 1 секундой ожидания основного потока. Обычно я смотрю вкладку «Производительность» Диспетчера задач. Иногда я запускаю код, и количество потоков будет колебаться между 2-6 дополнительными, а Commit Charge будет колебаться от 1044M до 1150M. Это то, чего я хочу.
В других случаях я запускаю один и тот же код (100 итераций), а количество потоков продолжает увеличиваться до более чем 63 дополнительных. И Commit Charge продолжает расти с 1044M до более чем 1272M.
Что я могу сделать, чтобы программа автоматически очищала потоки?
Если 'callConvertToPDF' запускается до завершения, новый поток будет выходить и очищаться. Вы выпускаете потоки внутри 'callConvertToPDF'? Я думаю, что файлы PS или PDF остаются открытыми после завершения преобразования. – kennyzx
@kennyzx Спасибо за ваш комментарий, который был полезен. Я отправил остальную часть кода на случай, если вам интересно, но ответ GroverBoy изменил ситуацию. Благодарю. –
Если я правильно понимаю этот код, вы читаете более 900 имен файлов, и вы начинаете как новый поток, так и новый процесс для каждого файла. Это верно? – Enigmativity