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));
    }