我有以下代码:
private static void SplitTilesRecursive(Image original, int level)
{
int mapWidth = GetMapWidth(level);
int tilesOnSide = mapWidth/TileSize;
using (Image resized = ResizeImage(original, new Size(mapWidth, mapWidth)))
{
for (int x = 0; x < tilesOnSide; x++)
for (int y = 0; y < tilesOnSide; y++)
{
CropAndSaveTile(resized, x, y, level);
}
}
if (level > 0)
SplitTilesRecursive(original, level - 1);
}
private static void CropAndSaveTile(Image image, int x, int y, int level)
{
var info = (CropInfo) o;
var cropArea = new Rectangle(x * TileSize, y * TileSize, TileSize, TileSize);
using (var bmpImage = new Bitmap(image))
using (Bitmap bmpCrop = bmpImage.Clone(cropArea, bmpImage.PixelFormat))
{
string filename = String.Format(TileFilename, level, x, y);
// the Portable Network Graphics (PNG) encoder is used implicitly
bmpCrop.Save(Path.Combine(OutputDir, filename));
Console.WriteLine("Processed " + filename);
}
}
该方法CropAndSaveTile
需要一段时间,所以我想使用线程池将该任务拆分到一个新线程。我尝试使用Task.Factory.StartNew
. 问题是我需要将这 4 个参数传递给线程,所以我必须创建一个可以强制转换为对象的类。
private class CropInfo
{
public CropInfo(Image image, int x, int y, int level)
{
Image = image;
X = x;
Y = y;
Level = level;
}
public Image Image { get; set; }
public int X { get; set; }
public int Y { get; set; }
public int Level { get; set; }
}
private static void SplitTilesRecursive(Image original, int level)
{
// ...
using (Image resized = ResizeImage(original, new Size(mapWidth, mapWidth)))
{
for (int x = 0; x < tilesOnSide; x++)
for (int y = 0; y < tilesOnSide; y++)
{
Task.Factory.StartNew(CropAndSaveTile, new CropInfo(resized, x, y, level));
}
}
// ...
}
private static void CropAndSaveTile(object o)
{
var info = (CropInfo) o;
// ...
}
这几乎可以工作。问题是new Bitmap(info.Image)
抛出一个ArgumentException
(参数无效)。我已经对此进行了测试,但没有使用Task.Factory.StartNew
,而是直接使用调用该方法CropAndSaveTile(new CropInfo(resized, x, y, level));
,它工作正常。和之间发生了一些事情 StartNew
,线程运行。这可能是由何时SplitTilesRecursive
结束循环并被resized
处理掉的同步问题吗?如果没有,我怎样才能正确地将多个参数传递给一个线程以用作线程池的一部分?