Распараллеливание GDI + Image Resizing .net

Я попытался распараллелить изменение размера jpeg-файлов с помощью .Net. Все мои попытки потерпели неудачу, потому что Graphics.DrawImage-func, похоже, блокируется во время активности. Попробуйте выполнить следующее:

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

Все потоки ждут в graph.DrawImage (). Есть ли способ повысить производительность кода с помощью других функций? Невозможно использовать Graphics.Draw с несколькими потоками? В реальном приложении размер нескольких изображений должен быть изменен одновременно (на четырехъядерном компьютере), а не всегда одинаково. Опубликованный код предназначен только для целей тестирования ...

Заранее спасибо

Изменить: обновлен код в соответствии с комментариями

15
задан PTa 15 September 2010 в 20:29
поделиться