次のコードがあります。
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
でしょうか? そうでない場合、スレッドプールの一部として使用されるスレッドに複数のパラメーターを適切に渡すにはどうすればよいですか?