Draw on a form by a separate thread

前端 未结 1 1736
醉话见心
醉话见心 2020-11-30 15:27

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

相关标签:
1条回答
  • 2020-11-30 16:18

    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

    formGraphics = e.Graphics;
    

    but at the end of the method e.Graphics is disposed, so you can't use it anymore, if your code got to

    Engine.Draw(formGraphics);
    

    you would get an exception.

    So basically you need to have a global

    Bitmap buffer = new Bitmap(this.Width, this.Height)
    

    in your asynced thread you would invoke your drawing to that Bitmap you can use

    Graphics g=Graphics.FromBitmap(buffer);//
    

    To get a graphics object, but remember you have to

    g.Dispose()
    

    it or wrap it in a

    using (Graphics g=Graphics.FromBitmap(buffer))
    {
    //do something here
    
    }
    

    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.

    //you need this line to use the tasks
    using System.Threading.Tasks;
    
    namespace WindowsFormsApplication1
    {
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
    
        public void Draw()
        {
            Bitmap buffer;
            buffer = new Bitmap(this.Width, this.Height);
            //start an async task
            Task.Factory.StartNew( () =>
            {
                    using (Graphics g =Graphics.FromImage(buffer))
                    {
                        g.DrawRectangle(Pens.Red, 0, 0, 200, 400);
                        //do your drawing routines here
                    }
                //invoke an action against the main thread to draw the buffer to the background image of the main form.
                this.Invoke( new Action(() =>
                {
                        this.BackgroundImage = buffer;
                }));
            });
    
        }
    
        private void button1_Click(object sender, EventArgs e)
        {
            //clicking this button starts the async draw method
            Draw();
        }
    
    }
    

    }

    0 讨论(0)
提交回复
热议问题