I'm trying to build a multithreaded game where I have a separate thread for painting on the form which is not the main thread. this brings us to thread-safe technics which I've read many articls about, but I'm not really sure I got it correctly.
my problem is that I have a structure where every data object is painting it self on the form so I didn't figure out how to implement it.
this is a snippet of my working mono-thread code:
public partial class Form1 : Form
{
GameEngine Engine;
public Form1()
{
InitializeComponent();
Engine = new GameEngine();
}
protected override void OnPaint(PaintEventArgs e)
{
Engine.Draw(e.Graphics);
}
}
class GameEngine
{
Maze Map;
List<Player> Players;
public void Draw(Graphics graphics)
{
Map.Draw(graphics);
foreach (var p in Players)
{
p.Draw(graphics);
}
}
}
so please can anyone give me a hint or a link to good article helping me to learn how to separate the drawing on an another thread?.
[Edit]
I managed to implement what I intended to do
and this is how I coded it
protected override void OnPaint(PaintEventArgs e)
{
formGraphics = e.Graphics;
DisplayThread = new Thread(new ThreadStart(Draw));
DisplayThread.Start();
}
private void Draw()
{
if (this.InvokeRequired)
{
this.Invoke(new DrawDelegate(this.Draw));
}
else
{
Engine.Draw(formGraphics);
}
}
but I got an ArgumentException : Parameter is not valid
would you please point to the error in that code
Best Answer
I think you will need to draw to a Bitmap, then in the OnPaint Method, draw that bitmap to the window. I will demonstrate in a moment.
As Hans pointed out, in the OnPaint method you are setting
but at the end of the method e.Graphics is disposed, so you can't use it anymore, if your code got to
you would get an exception.
So basically you need to have a global
in your asynced thread you would invoke your drawing to that Bitmap you can use
To get a graphics object, but remember you have to
it or wrap it in a
I am going to play with it for a few moments and see if I can get you a working sample
EDIT Here's your working sample. I started a new form and tossed a button on it. I changed the mainform backgroundimagelayout to none.
I think you need to be using .net 4.0 or better, if not using this, let me know I can change it to match your version... I think.
}