繁体   English   中英

Bitmap.Save“对象目前正在其他地方使用”线程问题

[英]Bitmap.Save “Object is currently in use elsewhere” Threading Issue

我有一些像这样的代码:

    public void SaveImage(int Counter)
    {
        var task = Task.Factory.StartNew(() =>
        {
            var image = FinalImage;
            if (image != null)
            {
                image.Save(FinalImageSaveLocation + "test" + Counter + ".bmp");
            }
        }, TaskCreationOptions.PreferFairness);
    }

我有一个for循环使用类似的代码创建x数量的图像:

for(int i = 0; i < 100; i++)
{
  Pencil.DrawImage(image, x, y); //Pencil is created at a initialisation stage
  SaveImage(i);                  //by Pencil = Graphics.FromImage(FinalImage);
}

我认为通过将SaveImage方法作为一项任务,这将加快速度,但我认为我得到的异常是因为循环的下一次迭代试图在Save发生时绘制到最终的图像对象。 我想我可以使用锁,但我担心会减慢速度吗?

有修复还是应该删除任务?

实际上,您无法同时从多个线程访问图像。 你必须做一些同步。 如果性能有问题,您可以执行以下技巧:

在保存方法中,锁定图像。 保存到内存流,释放锁定,最后保存到磁盘。 (因为磁盘IO非常慢)。

锁定部分仅在需要实际同步时才有用。 由于Bitmap不是线程安全的,因此您不应该首先使用多个线程访问它,因此同步应该不是问题。

只要您不同时执行此操作,绘制到位图并将其保存在另一个线程中就完全没问题了。 GDI +包含一个检查,以验证您不能同时从多个线程访问位图,这就是您获得异常的原因。

一个简单的解决方法是在开始绘制之前创建一个新的位图。 保存后将其置于任务中。 你必须仔细编写代码,如果保存位图的时间比绘图长,你仍然会遇到问题。 你的内存不足了。 信号量可以解决这个问题,将其初始化为您熟悉的位图数量。 取决于位图的大小。 然后在保存方法中的绘图方法Release()中调用WaitOne()。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM