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

时间:2014-01-28 07:39:30

标签: c# multithreading rotation picturebox

<code>enter image description here</code>

我只想在开始按钮点击时通过线程旋转图片框中的图像并且我面临错误“对象当前正在其他地方使用”我有测试锁和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 个答案:

答案 0 :(得分:2)

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

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

你可能需要做的是:

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

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