我有以下代碼:使用多線程的線程池
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
被處置時造成的同步問題嗎?如果不是,我怎樣才能正確地將多個參數傳遞給線程來作爲線程池的一部分?
你是否對所有任務使用'resized'的相同實例? – Tudor 2012-07-26 15:56:33