在一个线程中定义pictureBox1不断的从e盘获取图片然后进行计算但是老是出现线程间操作无效: 从不是创建控件“pictureBox1”的线程访问它。这个问题,请高手指教一下。其中public void jsplus(int x1, int x2, int y1, int y2, Image img)是计算图片颜色平均值然后在图片中添加些物体把添加物体的那部分区域涂色。代码如下: private void button1_Click(object sender, EventArgs e)
        {
            Thread thread = new Thread(CrossThreadFlush);
            thread.IsBackground = true;
            thread.Start();        }        private void CrossThreadFlush()
        {
            //将代理绑定到方法
            FlushClient fc = new FlushClient(ThreadFuntion);
            while (true)
            {
                //将sleep和无限循环放在等待异步的外面
                Thread.Sleep(1000);
                ThreadFuntion();
            }        }        private void ThreadFuntion()
        {
            //pictureBox1.Image = Image.FromFile("e:\\a.bmp", true);
            //this.pictureBox1.Refresh();
            //try
            //{
                String path = String.Format("e:\\a.bmp");
                Bitmap bitmp1;
                Bitmap bitmp = new Bitmap(Image.FromFile("e:\\a.bmp", true));
                bitmp1 = bitmp;
                this.pictureBox1.Image = bitmp1;
                this.pictureBox1.Refresh();
                jsplus(st1, st2, st3, st4, this.pictureBox1.Image); //其中的参数是图片中的左边
                jsplus(st5, st6, st7, st8, this.pictureBox1.Image);
                jsplus(st9, st10, st11, st12, this.pictureBox1.Image);
                jsplus(st13, st14, st15, st16, this.pictureBox1.Image);
                jsplus(st17, st18, st19, st20, this.pictureBox1.Image);
                // MessageBox.Show(p1 + "\n" + p2 + "\n" + p3 + "\n" + p4 + "\n" + p5); 
            //}
            //catch (Exception e) {
            //    MessageBox.Show(e.Message);
            //}
        }public void jsplus(int x1, int x2, int y1, int y2, Image img)
        {
            g = this.pictureBox1.CreateGraphics();            int r = 0, g1 = 0, b = 0, t = 0;            if (img != null)
            {                Bitmap process = (Bitmap)img;
                Color pixel;
                for (int x = x1; x < x2 + 1; x++)
                {
                    for (int y = y1; y < y2 + 1; y++)
                    {                        pixel = process.GetPixel(x, y);
                        r += pixel.R;
                        g1 += pixel.G;
                        b += pixel.B;
                    }
                }                t = (r + g1 + b) / (3 * (x2 - x1) * (y2 - y1));
                //string  m = t.ToString();                //   MessageBox.Show(m);
            }            int vcr1 = 0, vcr2 = 0, vcr3 = 0, vcr4 = 0, vcr5 = 0, vcr6 = 0, vcr7 = 0, vcr8 = 0, vcr9 = 0, vcr10 = 0, vcr11 = 0, vcr12 = 0, vcr13 = 0, vcr14 = 0, vcr15 = 0, vcr16 = 0;
            // string p1=null;
            if (x1 > st1 - 1 & x2 < st2 + 1 & y1 > st3 - 1 & y2 < st4 + 1)
            {                vcr1 = Math.Abs(t - sc1);
                if (vcr1 >= 4)
                {
                   
                    g.FillRectangle(Brushes.Red, st1, st3, st2 - st1, st4 - st3);
                                    }
                else
                {
                   
                    g.FillRectangle(Brushes.White, st1, st3, st2 - st1, st4 - st3);
                }
                m1 = t.ToString();
                
            }

解决方案 »

  1.   

    private void CrossThreadFlush()
    {
        //将代理绑定到方法
        FlushClient fc = new FlushClient(ThreadFuntion);
        while (true)
        {
        //将sleep和无限循环放在等待异步的外面
        Thread.Sleep(1000);
        this.BeginInvoke((MethodInvoker)delegate()
        {
            ThreadFuntion();
        });  
    }  }
      

  2.   


    两种方法 
    1.可以在主线程中添加一个语句CheckForillegalCrossThreadCalls = false; 
    2.用委托,如下在主线程中调用test()方法就行了。 private delegate void SetTextCallbakc(); 
    //主线程中调用方法 
    public void test() 
            { 
                SetTextCallbakc stcb = new SetTextCallbakc(callbakc); 
                Invoke(stcb);  
            } //具体要调用的方面 
    public void callbakc() 
    {}
      

  3.   

    最简单的方法,在pageload事件里面加上这句
    Form1.CheckForIllegalCrossThreadCalls = false;
    那个报的错是说,不允许跨线程调用控件。
      

  4.   

    //在Form构造函数里面加上
    Form.CheckForIllegalCrossThreadCalls  = false;
      

  5.   

    从源头解决你的问题:
    http://sun77.blog.163.com/blog/static/9798657320094525217768/
      

  6.   

    在Form中加了Form.CheckForIllegalCrossThreadCalls = false;如果在区域里颜色值变化vrc1》=4时给这个区域涂色时会报这里报GDI+ 中发生一般性错误也就是在:
    public void jsplus(int x1, int x2, int y1, int y2, Image img)的
    if (x1 > st1 - 1 & x2 < st2 + 1 & y1 > st3 - 1 & y2 < st4 + 1)
                {
                    //g = this.pictureBox1.CreateGraphics();
                    vcr1 = Math.Abs(t - sc1);
                    if (vcr1 >= 4)
                    {
                       
                        g.FillRectangle(Brushes.Red, st1, st3, st2 - st1, st4 - st3);//这里报GDI+ 中发生一般性错误
                                        }
                    else
                    {
                       
                        g.FillRectangle(Brushes.White, st1, st3, st2 - st1, st4 - st3);
                    }
                  
                    m1 = t.ToString();
                    
                }  }
      

  7.   

    herbt这位朋友我根据你的方法加后它提示:在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke。