使用线程

时间:2018-05-24 16:33:21

标签: c# multithreading picturebox

每次点击pictureBox时,我都会在列表中添加Car类型的对象。 我想点击picutreBox后立即移动它们。

这是我的代码

private Thread t;
private void pictureBox1_MouseClick_1(object sender, MouseEventArgs e)
{                
    list.Add(new Car(e.X, e.Y, 40, 40));
    br++;
    t = new Thread(Draw);
    t.Start();  
}

绘制:

private void Draw()
{
    Graphics g = pictureBox1.CreateGraphics();           
    for(int i = 0; i < 1000; i++)
    {
        list[br].DrawCar(g, Color.Red);
        list[br].Move();               
        Thread.Sleep(100);
        pictureBox1.Invoke(
            (MethodInvoker)delegate
            {
                pictureBox1.Refresh();
            });
    }            
    g.Dispose();
}

我遇到的问题如下:

  1. 当我第一次点击时,它移动得很好,但是一旦我再次点击,车就会停下来,下一辆车开始移动。

  2. 我点击表格越多,车速越快,我不知道为什么

  3. 当我退出表格时,我得到一个例外:
  4.   

    System.InvalidOperationException:'Invoke或BeginInvoke不能   调用控件直到创建窗口句柄。'

2 个答案:

答案 0 :(得分:1)

  1. 第一辆车因为br递增而停止,Draw功能现在移动列表中的第二辆车。
  2. 如果多次单击图片框,将会有多个线程运行Draw功能,并且他们都在移动同一辆车(参见1.)。
  3. 当表单关闭且线程仍在运行时,线程会尝试访问图片框。它可能不存在了。
  4. 解决方案

    1. 使br成为局部变量并将br作为参数传递给thread.Start()方法。
    2. 应由1修正。
    3. 在表单的OnClosing中停止所有线程

答案 1 :(得分:1)

我在你的代码中看到了几个红色标记。

每次创建一个新线程。旧线程会发生什么?同时创建一个新的线程来移动每辆车并不理想。

使用br来索引列表中的哪个Car进行移动和绘制。当你添加第二辆车时,br现在为1,所以现在第一个Draw线程将使用list [1]。现在你有2个线程都移动了第二辆车。这就是为什么第一辆车停止移动而第二辆车开始移动的原因。

调用pictureBox刷新也不理想。

我会更喜欢这样做:

List<System.Windows.Forms.Timer> timers =
  new List<System.Windows.Forms.Timer>();
List<Car> list = new List<Car>();

private void button1_Click(object sender, EventArgs e)
{
  Car car = new Car(50, 50, 40, 40);
  list.Add(car);
  Timer timer = new Timer();
  timer.Tick += Timer_Tick;
  timer.Interval = 100;
  timer.Tag = car;
  timer.Start();
  timers.Add(timer);
}

private void Timer_Tick(object sender, EventArgs e)
{
  Car car = (Car)((sender as Timer).Tag);
  car.Move();
  pictureBox1.Invalidate();
}

private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
  Graphics g = e.Graphics;
  g.Clear(Color.White);

  foreach (Car car in list.ToArray())
  {
    car.DrawCar(g, Color.Blue);
  }
}

car.Move和DrawCar可能还有其他问题。