Converting MagicImageCollection to Base64 in parallel

Sep 16, 2014 at 10:42 PM
I have a collection of images I need to convert to PNG, then to Base64. Iterating through the collection one at a time takes about a second per image for the conversion to string. I tried to use PLINQ to do the conversion like this:
                returnImage.AsParallel().ForAll(test => test.Format=MagickFormat.Png);
                returnImage.AsParallel().AsOrdered().ForAll(test => test.ToBase64());
And the setting to PNG works fine, the ToBase64 throws an error:
An exception of type 'System.ArgumentNullException' occurred in GraphicsMagick.NET-AnyCPU.dll but was not handled in user code

Value cannot be null.\r\nParameter name: inArray

Can parallelism be used with MagicImageCollection? and if not, does anyone know of a way to make that conversion to base64 faster?
Coordinator
Sep 17, 2014 at 5:06 AM
Are you using GraphicsMagick.NET or Magick.NET? Please use the other discussion board if you are using GraphicsMagick.NET next time.

Parallelism can be used as long as you are not making changes to a single image in multiple threads. Which class/method is raising the ArgumentNullException exception inside the ToBase64 method?
Sep 17, 2014 at 3:08 PM
Sorry, I will use the correct board. This is where Google searches brought me.

All I have available to me is the dll, so I do not know which method is throwing the error.
Coordinator
Sep 17, 2014 at 8:31 PM
Can you post a stack-trace or link to a sample project/class that can be used to reproduce the error?
Sep 18, 2014 at 6:24 PM
Edited Sep 18, 2014 at 7:30 PM
***Edited to remove bad code I posted by mistake

I am using v4.0.30319 of GraphicsMagick.NET.AnyCPU

The code is very simple - I have a byte array containing a multipage tiff. From there the applicable code is
MagickImageCollection returnImage = null;
using (MemoryStream ms = new MemoryStream(ByteData))
{
    try
    {
        returnImage = new MagickImageCollection(ms);
    
        returnImage.AsParallel().ForAll(a => a.Format=MagickFormat.Png);
        var query = from f in returnImage.AsParallel().AsOrdered() 
                            let p = f.ToBase64()
                            select p;
        foreach (var d in query)
        {
            *process returned strings*
        }
    }
    catch (Exception e)
    {
        *exception handling*
    }
}
Exception occurs and does not hit my exception handler, it breaks on the Tobase64 line:
An exception of type 'System.ArgumentNullException' occurred in GraphicsMagick.NET-AnyCPU.dll but was not handled in user code

Stack trace:

at GraphicsMagick.MagickImage.ToBase64()
at TestProg.<ConvertBytesToString>b__10(MagickImage a)
at System.Linq.Parallel.ForAllOperator1.ForAllEnumerator1.MoveNext(TInput& currentElement, Int32& currentKey)
at System.Linq.Parallel.ForAllSpoolingTask`2.SpoolingWork()
at System.Linq.Parallel.SpoolingTaskBase.Work()

Detail:
System.ArgumentNullException was unhandled by user code
HResult=-2147467261
Message=Value cannot be null.
Parameter name: inArray
Source=GraphicsMagick.NET-AnyCPU
ParamName=inArray
StackTrace:
   at GraphicsMagick.MagickImage.ToBase64()
   at TestProg.<ConvertBytesToString>b__10(MagickImage a) 
   at System.Linq.Parallel.ForAllOperator`1.ForAllEnumerator`1.MoveNext(TInput& currentElement, Int32& currentKey)
   at System.Linq.Parallel.ForAllSpoolingTask`2.SpoolingWork()
   at System.Linq.Parallel.SpoolingTaskBase.Work()
InnerException:
Coordinator
Sep 19, 2014 at 8:09 AM
I can reproduce the issue. Not sure what is causing this yet but I am working on a fix. I will get back to you when this issue has been fixed.
Sep 19, 2014 at 3:11 PM
Thank you for all your help!
Coordinator
Sep 19, 2014 at 9:10 PM
The bug has been found and will be fixed in GraphicsMagick.NET 1.3.20.2 that will be released soon.