C# 使用线程池进行多线程处理
我有以下代码:C# 使用线程池进行多线程处理,c#,multithreading,c#-4.0,taskfactory,C#,Multithreading,C# 4.0,Taskfactory,我有以下代码: private static void SplitTilesRecursive(Image original, int level) { int mapWidth = GetMapWidth(level); int tilesOnSide = mapWidth/TileSize; using (Image resized = ResizeImage(original, new Size(mapWidth, map
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);
}
}
这几乎奏效了。问题是
新位图(info.Image)
抛出参数异常
(参数无效)。我没有使用Task.Factory.StartNew
测试这个方法,而是直接使用CropAndSaveTile(新的CropInfo(resized,x,y,level))调用这个方法代码>并且工作正常。StartNew
和线程运行之间发生了一些事情。这是否是由于SplitTilesRecursive
结束循环并处理大小调整后的
时导致的同步问题?如果没有,我如何正确地将多个参数传递给一个线程,作为线程池的一部分使用?为什么必须创建一个类?您可以这样做:
Task.Factory.StartNew(()=>CropandSaveTile(resized, y, y, level));
该语言将在封面下为您创建一个类作为“闭包”。尝试在循环中使用x
和y
的本地副本:
for (int x = 0; x < tilesOnSide; x++)
for (int y = 0; y < tilesOnSide; y++)
{
int x1 = x;
int y1 = y;
Task.Factory.StartNew(() => CropAndSaveTile(resized, x1, y1, level));
}
for(int x=0;xCropAndSaveTile(已调整大小,x1,y1,级别));
}
这保证了每个lambda都能看到一对独立的x
和y
值。我担心闭包会导致问题,例如,如果x或y在线程执行之前发生变化。闭包的作用与您尝试的相同。它将把x和y中的值复制到编译器生成的类的成员中。唯一的问题是您是否修改了引用变量数据。i、 e.如果您更改了图像引用的内存。但是,如果你手动创建了一个类,你也会遇到同样的问题好吧,但我想问的是,我该怎么做,这样我就不会遇到同样的问题了?我以为我通过使用一个类来解决这个问题,但我忽略了一个事实,即对象没有被复制到实例,而是被引用。图像也有同样的问题吗?我假设ResizeImage正在制作数据的新副本,如果您不让任何其他对象访问resized,您不会有问题。您是否在所有任务中使用相同的resized
实例?
for (int x = 0; x < tilesOnSide; x++)
for (int y = 0; y < tilesOnSide; y++)
{
int x1 = x;
int y1 = y;
Task.Factory.StartNew(() => CropAndSaveTile(resized, x1, y1, level));
}