在c#中通过多线程旋转图片框

时间:2021-10-31 21:02:41

在c#中通过多线程旋转图片框

I just want to rotate images in pictureboxes via threads when start button click and i face error "Object is currently in use elsewhere" i have test lock and picturebox.invalidate but it has no use. First I have assign images into pictureboxes and with place function i have assign priority

我只是想在开始按钮点击时通过线程旋转图片框中的图像,我面临错误“对象当前正在其他地方使用”我有测试锁和picturebox.invalidate但它没有用。首先,我已将图像分配到图片框中,并且使用场所功能我已分配优先级

Thread thread, td;

    public Form1()
    {
        InitializeComponent();
        this.pictureBox1.Image = this.Draw(this.pictureBox1.Width, this.pictureBox1.Height,1);
        comboBox1.SelectedIndex = 0;
        this.pictureBox2.Image = this.Draw(this.pictureBox2.Width, this.pictureBox2.Height,2);
        comboBox2.SelectedIndex = 0;
        this.pictureBox3.Image = this.Draw(this.pictureBox3.Width, this.pictureBox3.Height,3);
        comboBox3.SelectedIndex = 0;
    }

    public Bitmap Draw(int width, int height, int num)
    {
        var bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
        var graphics = Graphics.FromImage(bitmap);
        graphics.SmoothingMode = SmoothingMode.AntiAlias;
        if(num==1)
            graphics.FillRectangle(new SolidBrush(Color.SteelBlue), 10, 10, 100, 100);
        if (num == 2)
            graphics.FillEllipse(new SolidBrush(Color.YellowGreen), 0, 25, 100, 50);
        if (num == 3)
            graphics.FillRectangle(new SolidBrush(Color.Tomato), 10, 10, 50, 100);
        return bitmap;
    }

    private void button9_Click(object sender, EventArgs e)
    {

    }

    private void button7_Click(object sender, EventArgs e)
    {
        System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false; // disable cross-threading control error

        thread = new Thread(new ThreadStart(Display1));
        place(ref thread, comboBox1.SelectedIndex);
        thread.Start();

        thread = new Thread(new ThreadStart(Display2));
        place(ref thread, comboBox2.SelectedIndex);
        thread.Start();

        thread = new Thread(new ThreadStart(Display3));
        place(ref thread, comboBox3.SelectedIndex);
        thread.Start();
    }

    protected void Display1()
    {
        for (long i = 0L; i < 200000; i++)
        {
            //if (i % 5000 == 0)
            {
                Image img = pictureBox1.Image;
                img.RotateFlip(RotateFlipType.Rotate90FlipNone);
                pictureBox1.Image = img;
            }
        }
        //thread.Abort();
    }

    protected void Display2()
    {   
        for (long i = 0L; i < 200000; i++)
        {                
            //if (i % 50000 == 0)
            {
                Image img = pictureBox2.Image;
                img.RotateFlip(RotateFlipType.Rotate90FlipNone);
                pictureBox2.Image = img;
            }
        }
       // thread.Abort();
    }

    protected void Display3()
    {
        for (long i = 0L; i < 200000; i++)
        {
            //if (i % 5000 == 0)
            //{
            Image img = pictureBox3.Image;
            img.RotateFlip(RotateFlipType.Rotate90FlipNone);
            pictureBox3.Image = img;
            //}
        }
      //  thread.Abort();
    }

    public void place(ref Thread p, int x)
    {
        switch (x)
        {
            case 0:
                p.Priority = ThreadPriority.Lowest;
                break;

            case 1:
                p.Priority = ThreadPriority.BelowNormal;
                break;

            case 2:
                p.Priority = ThreadPriority.Normal;
                break;

            case 3:
                p.Priority = ThreadPriority.AboveNormal;
                break;

            case 4:
                p.Priority = ThreadPriority.Highest;
                break;
        }
    }

    private void button10_Click(object sender, EventArgs e)
    {
        Application.Exit();
        if (td.IsAlive)
            td.Abort();
        if (thread.IsAlive)
            thread.Abort();
    }

1 个解决方案

#1


2  

The primary problem you're going to run into here is that you can't update those controls from other threads. Updates must be done on the UI thread.

您将遇到的主要问题是您无法从其他线程更新这些控件。必须在UI线程上进行更新。

You might be able to get the image and rotate it, updating it (i.e. pictureBox1.Image = img;) will probably give you a cross-thread exception.

您可能能够获取图像并将其旋转,更新它(即pictureBox1.Image = img;)可能会给您一个跨线程异常。

Probably what you'll need to do is this:

可能你需要做的是:

Image img;
this.Invoke((MethodInvoker)delegate { img = pictureBox1.Image; });
img.RotateFlip(RotateFlipType.Rotate90FlipNone);
this.Invoke((MethodInvoker)delegate { pictureBox1.Image = img; });

As I said, you might get away without the first Invoke call, but you certainly can't call the Image setter except on the UI thread.

正如我所说,你可能会在没有第一个Invoke调用的情况下离开,但除了UI线程之外你肯定无法调用Image setter。

#1


2  

The primary problem you're going to run into here is that you can't update those controls from other threads. Updates must be done on the UI thread.

您将遇到的主要问题是您无法从其他线程更新这些控件。必须在UI线程上进行更新。

You might be able to get the image and rotate it, updating it (i.e. pictureBox1.Image = img;) will probably give you a cross-thread exception.

您可能能够获取图像并将其旋转,更新它(即pictureBox1.Image = img;)可能会给您一个跨线程异常。

Probably what you'll need to do is this:

可能你需要做的是:

Image img;
this.Invoke((MethodInvoker)delegate { img = pictureBox1.Image; });
img.RotateFlip(RotateFlipType.Rotate90FlipNone);
this.Invoke((MethodInvoker)delegate { pictureBox1.Image = img; });

As I said, you might get away without the first Invoke call, but you certainly can't call the Image setter except on the UI thread.

正如我所说,你可能会在没有第一个Invoke调用的情况下离开,但除了UI线程之外你肯定无法调用Image setter。