Images in GDI+ are not thread safe. What it means, basically - you cannot use one image from 2 threads simultaneously without some additional changes to your code.
Look at following pseudo code:
public void SetPixels()
{
var bmp = new Bitmap("Some image");
var t = new Task(() => { for (int i = 0; i < 1000000; i++) {
bmp.SetPixel(0, 1, Color.Black); } });
var t2 = new Task(() => { for (int i = 0; i < 1000000; i++) {
bmp.SetPixel(0, 1, Color.Black); } });
t.Start();
t2.Start();
}
At some moment here you will have "InvalidOperationException", which you described, since 2 different threads are setting colors of pixel in one image at same time.
You have to make lock each time, before you accessing to you bitmap.
On class level, declare variable
private object _locker = new object();
And, in pseudo code, similar construction, as above, but which will execute without exceptions:
public void SetPixels()
{
var bmp = new Bitmap("Some image");
var t = new Task(() => { for (int i = 0; i < 1000000; i++)
{ lock (_locker) { bmp.SetPixel(0, 1, Color.Black); } } });
var t2 = new Task(() => { for (int i = 0; i < 1000000; i++)
{ lock (_locker) { bmp.SetPixel(0, 1, Color.Black); } } });
t.Start();
t2.Start();
}
lock is built-in C# language construction; you can find info about it on MSDN.