我在Linux中使用多线程代码通过Imagemagick生成了数百万的bmp,但是由于某些原因,我遇到了我无法处理的以下错误之一(没有堆栈跟踪):
dotnet: MagickCore/pixel.c:138: ClonePixelChannelMap: Assertion 'channel_map != (PixelChannelMap *) NULL' failed.
或
dotnet: MagickCore/semaphore.c:452: UnlockSemaphoreInfo: Assertion 'semaphore_info != (SemaphoreInfo *) NULL' failed.
或
dotnet: MagickCore/option.c:2137: CloneImageOptions: Assertion 'clone_info->signature == MagickCoreSignature' failed.
我的try-catch块无法处理这些错误,因此我的程序立即关闭。
错误是非常随机的,因为在另一次尝试中对Imagemagick的相同输入顺利通过了。
我使用 Include =“ Magick.NET-Q16-x64” Version =“ 7.11.0.0”
我还尝试使用“ Magick.NET-Q8-x64”和以前版本的imagemagic获得相同的结果。
Linux 4.18.0-3-amd64#1 SMP Debian 4.18.20-2(2018-11-23)x86_64 GNU / Linux
这是线程中的代码(我以9个线程运行应用程序)
public virtual void GeneratePictureForCurrSpin()
{
do
{
GenerateInternal();
} while (!isAllPicturesGenerated());
}
public override void GenerateInternal()
{
symbols = symbolParser.ParseSymbols(config, spins[currLocalSpin].symbols);
img = (MagickImage)SpinGenerator.rl.emptyImg.Clone();
bgImg = SpinGenerator.rl.bg;
img.Composite(bgImg, new PointD(config.BgX, config.BgY),ImageMagick.CompositeOperator.Over);
reelsBgImg = SpinGenerator.rl.reelsBg;
img.Composite(reelsBgImg, CompositeOperator.Over);
PointD startPoint = new PointD(config.StartOffsetX, config.StartOffsetY);
MagickImage sym;
for(int i = 0; i < symbols.Count; i++)
{
List<int> symbolsOnReel = symbols[i];
for(int j = 0; j < symbolsOnReel.Count; j++)
{
var newPoint = new PointD(startPoint.X + i * (config.SymbolWidth + config.OffsetX), startPoint.Y + j * (config.SymbolHeight + config.OffsetY));
sym = SpinGenerator.rl.symbols[symbolsOnReel[j]-1];
img.Composite(sym, newPoint, ImageMagick.CompositeOperator.Over);
}
}
bool isFreeSpin = (spins[currLocalSpin].betValue == 0)?true:false;
GenerateBottomBar(isFreeSpin);
ShowTokensValue(spins[currLocalSpin].coins);
ResizeImage();
int fileNr = spins[currLocalSpin].spinNr;
String dir = "Resources/Result/" + GAME_NAME + "/" + betValue;
SaveImg(dir , fileNr);
img.Dispose();
IncrementSpinValues();
}
public virtual void GenerateBottomBar(bool isFreeSpin)
{
var pos = (isFreeSpin)?1:0;
bottomBar = SpinGenerator.rl.bottomBars[pos];
PointD startPoint = new PointD(0,config.BgHeight);
img.Composite(bottomBar,startPoint);
}
private void ShowTokensValue(int tokens)
{
if(tokens < 10)
{
var tokenValueImg = SpinGenerator.rl.tokensValues[tokens];
tokenValueImg.Resize(90,60);
img.Composite(tokenValueImg, new PointD(tokenValueStartX + tokenValueImgWidth, tokenValueStartY),ImageMagick.CompositeOperator.Over);
}
else{
int a = tokens / 10;
int b = tokens % 10;
var tokenValueImgA = SpinGenerator.rl.tokensValues[a];
tokenValueImgA.Resize(90,55);
img.Composite(tokenValueImgA, new PointD(tokenValueStartX, tokenValueStartY),ImageMagick.CompositeOperator.Over);
var tokenValueImgB = SpinGenerator.rl.tokensValues[b];
tokenValueImgB.Resize(90,55);
img.Composite(tokenValueImgB, new PointD(tokenValueStartX+ tokenValueImgWidth, tokenValueStartY),ImageMagick.CompositeOperator.Over);
}
var tokensTxtImg = SpinGenerator.rl.tokensTxt;
img.Composite(tokensTxtImg, new PointD(tokenTxtStartX, tokenTxtStartY),ImageMagick.CompositeOperator.Over);
}
internal void ResizeImage()
{
img.Format = ImageMagick.MagickFormat.Bmp3;
img.Depth = 16;
img.Resize(new MagickGeometry("600, 450!"));
//img.Quality = 100;
}
internal void SaveImg(String dir , int fileNr)
{
System.IO.Directory.CreateDirectory(dir);
img.Write(dir + "/" +"s" + fileNr + ".bmp");
ClearImg();
}
internal virtual void IncrementSpinValues()
{
currLocalSpin++;
currSpin++;
}