【问题标题】:Cross-thread operation not valid for invalidating graphics object跨线程操作对无效图形对象无效
【发布时间】:2013-10-26 17:29:11
【问题描述】:

我正在尝试使用计时器创建每 500 毫秒重绘一次的图形,但我一直遇到跨线程操作。有人可以告诉我为什么会这样吗?

错误:

Cross-thread operation not valid: Control 'GraphicsBox' accessed from a thread other than the thread it was created on.

我正在使用 WinForms,并且在主窗体中有一个名为“GraphicsBox”的 PictureBox:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;

namespace NamespaceName
{
    public partial class FormName : Form
    {
        Graphics g;

        public FormName()
        {
            InitializeComponent();
            System.Timers.Timer t = new System.Timers.Timer();
            t.Interval = 500;
            t.Enabled = true;
            t.Elapsed += (s, e) => this.GraphicsBox.Invalidate(true);
        }

        private void FormName_Load(object sender, EventArgs e)
        {
            this.GraphicsBox.Paint += new PaintEventHandler(OnPaint);
        }

        protected void OnPaint(object sender, PaintEventArgs e)
        {
            g = e.Graphics;
            //Draw things
        }
    }
}

有什么方法可以从计时器的“滴答声”(或“已过”)触发OnPaint 事件?我相信这会成功。我要做的就是重绘图形对象,我将更改代码中的内容以使其以不同的方式绘制。

【问题讨论】:

  • 为什么不直接使用 system.windows.forms.timer?这将自动使用正确的线程...
  • @MarcGravell 叹了口气,我知道它必须是简单的...谢谢!
  • 这段代码其实是有效的,从线程池线程调用Invalidate()就可以了。

标签: c# winforms


【解决方案1】:

这里的主要问题是至少有 3 个名为 Timer 的类,并且可能更多(在不同的命名空间中,但具有不同的行为)。您正在使用一个在工作线程上回调的线程,而 UI 控件由于线程关联性而不喜欢这样。

如果您切换到System.Windows.Forms.Timer,它将调用 UI 线程上的回调(可能是通过同步上下文,但我猜它可能直接使用消息循环实现)。那么这不是跨线程操作,并且可以正常工作。

【讨论】:

    【解决方案2】:

    您在错误的线程上调用 GraphicsBox 对象,System.Timers.Timer.Elapsed 在不同的(后台)线程上调用。

    你可以——

    a)切换到使用System.Windows.Forms.Timer,它将与GraphicsBox在同一线程上运行

    b) 又快又讨厌 -

    t.Elapsed += (s, e) => this.Invoke(new MethodInvoker(delegate(){ this.GraphicsBox.Invalidate(true); }));
    

    【讨论】:

      猜你喜欢
      • 2011-07-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多