2

タイマーを使用して 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タイマーの「ティック」(または「経過」) からイベントを発生させる方法はありますか? 私はそれがうまくいくと信じています。私がやろうとしているのは、グラフィックス オブジェクトを再描画することだけです。別の方法で描画されるようにコードを変更します。

4

2 に答える 2

2

ここでの主な問題は、少なくとも 3 つの名前の付いたクラスがTimerあり、おそらくそれ以上の名前が付けられていることです (名前空間は異なりますが、動作は異なります)。ワーカー スレッドでコールバックするものを使用していますが、UI コントロールはスレッド アフィニティのためにそれを好みません。

それに切り替えるとSystem.Windows.Forms.Timer、UI スレッドでコールバックが呼び出されます (おそらく同期コンテキスト経由ですが、メッセージ ループを直接使用して実装される可能性があると思います)。これはクロススレッド操作ではなく、正常に機能します。

于 2013-10-18T01:24:58.777 に答える