【问题标题】:Rotate picturebox via multithreading in c#在c#中通过多线程旋转图片框
【发布时间】:2014-02-19 09:29:03
【问题描述】:

我只想在单击开始按钮时通过线程旋转图片框中的图像,我遇到错误“对象当前正在其他地方使用”我有测试锁和图片框。无效但它没有用。 首先,我将图像分配到图片框中,并通过放置功能分配优先级

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();
    }

【问题讨论】:

  • 你真的需要为此使用多线程吗?用定时器怎么样?

标签: c# multithreading rotation picturebox


【解决方案1】:

您将在此处遇到的主要问题是您无法从其他线程更新这些控件。更新必须在 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 就逃脱了,但您当然不能调用 Image 设置器,除非在 UI 线程上。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-20
    • 2011-05-07
    • 1970-01-01
    • 2018-07-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多