I've tried to parallelize the resizing of jpegs using .Net. All my tries failed, because the Graphics.DrawImage-func seems to lock while active. Try the following snipped:
Sub Main()
Dim files As String() = IO.Directory.GetFiles("D:\TEMP")
Dim imgs(25) As Image
For i As Integer = 0 To 25
imgs(i) = Image.FromFile(files(i))
Next
Console.WriteLine("Ready to proceed ")
Console.ReadLine()
pRuns = 1
For i As Integer = 0 To 25
Threading.Interlocked.Increment(pRuns)
Threading.ThreadPool.QueueUserWorkItem(New Threading.WaitCallback(AddressOf LongTerm), imgs(i))
Next
Threading.Interlocked.Decrement(pRuns)
pSema.WaitOne()
Console.WriteLine("Fin")
Console.ReadLine()
End Sub
Sub LongTerm(ByVal state As Object)
Dim newImageHeight As Integer
Dim oldImage As Image = CType(state, Image)
Dim newImage As Image
Dim graph As Graphics
Dim rect As Rectangle
Dim stream As New IO.MemoryStream
Try
newImageHeight = Convert.ToInt32(850 * oldImage.Height / oldImage.Width)
newImage = New Bitmap(850, newImageHeight, oldImage.PixelFormat)
graph = Graphics.FromImage(newImage)
rect = New Rectangle(0, 0, 850, newImageHeight)
With graph
.CompositingQuality = Drawing2D.CompositingQuality.HighQuality
.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
End With
'Save image to memory stream
graph.DrawImage(oldImage, rect)
newImage.Save(stream, Imaging.ImageFormat.Jpeg)
Catch ex As Exception
Finally
If graph IsNot Nothing Then
graph.Dispose()
End If
If newImage IsNot Nothing Then
newImage.Dispose()
End If
oldImage.Dispose()
stream.Dispose()
Console.WriteLine("JobDone {0} {1}", pRuns, Threading.Thread.CurrentThread.ManagedThreadId)
Threading.Interlocked.Decrement(pRuns)
If pRuns = 0 Then
pSema.Set()
End If
End Try
End Sub
All threads wait at graph.DrawImage(). Is there a way to speed up code performance using other functions? Is it impossible to use Graphics.Draw with multiple threads? In the real application multiple images should be resized at the same time (on a quad-core pc), not always the same. The posted code is only for testing purposes...
Thanks in advance
Edit: Updated the code according to comments