I know of course that I can not draw onto the same Graphics
object from different threads, but is it also true that I can not draw to different Graphics
objects in different threads?
Consider the following console program:
class Program
{
static ThreadDrawer[] drawers;
static void Main(string[] args)
{
int numThreads = 8;
drawers = new ThreadDrawer[numThreads];
for (int i = 0; i < numThreads; i++)
{
drawers[i] = new ThreadDrawer();
drawers[i].Start();
}
for (int i = 0; i < numThreads; i++)
{
drawers[i].Wait();
}
Console.WriteLine("Complete.");
Console.ReadKey();
}
class ThreadDrawer
{
private Thread thread;
private AutoResetEvent resetEvent;
public ThreadDrawer()
{
thread = new Thread(DrawRandomCircles);
resetEvent = new AutoResetEvent(false);
}
public void Start()
{
thread.Start();
}
public void Wait()
{
resetEvent.WaitOne();
}
public void DrawRandomCircles()
{
Random r = new Random(Environment.TickCount);
using (Bitmap b = new Bitmap(1000, 1000))
using (Graphics g = Graphics.FromImage(b))
{
for (int i = 0; i < 100000; i++)
{
g.DrawEllipse(Pens.Red, new Rectangle(r.Next(1000), r.Next(1000), 200, 200));
}
}
resetEvent.Set();
}
}
}
The program creates a Bitmap
in each thread and proceeds to draw random ellipses on it using a Graphics
object, also generated per thread from the Bitmap
.
Due to a requirement to build for .net2
the multithreading is implemented using Thread
s and AutoResetEvent
s instead of TPL.
The program executes without throwing an exception, but it executes serially. Using n
threads multiplies execution time by n
and it is clear to see using the task manager that only one core is being used.
Important to take note that none of this is tied to any UI element.
What is going on here? Is the Graphics
object locking on a static object?
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…