我有一些像这样的代码:
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发生时绘制到最终的图像对象。我想我可以使用锁,但我担心会减慢速度吗?
是否有修复或我应该删除任务?
答案 0 :(得分:3)
实际上,您无法同时从多个线程访问图像。你必须做一些同步。如果性能有问题,您可以执行以下技巧:
在保存方法中,锁定图像。保存到内存流,释放锁定,最后保存到磁盘。 (因为磁盘IO非常慢)。
锁定部分仅在需要实际同步时才有用。由于Bitmap不是线程安全的,因此您不应该首先使用多个线程访问它,因此同步不应该是一个问题。
答案 1 :(得分:2)
只要不同时执行此操作,绘制到位图并将其保存在另一个线程中就完全可以了。 GDI +包含一个检查,以验证您不会同时从多个线程访问位图,这就是您获得异常的原因。
一个简单的解决方法是在开始绘图之前创建 new 位图。保存后将其置于任务中。你必须仔细编写代码,如果保存位图的时间比绘图长,你仍然会遇到问题。你的内存不足了。信号量可以解决这个问题,将其初始化为您熟悉的位图数量。取决于位图的大小。然后在绘图方法中调用WaitOne(),在保存方法中调用Release()。