代码之家  ›  专栏  ›  技术社区  ›  FlyingStreudel

调用线程无法访问此对象,因为其他线程拥有它

  •  8
  • FlyingStreudel  · 技术社区  · 16 年前

    所以我在C/WPF中制作了一个简单的砖块游戏。我在使用计时器时遇到了一个问题,我觉得这可能是一个简单的修复方法,但下面是正在发生的事情。每当t经过时,它试图调用update(),但是当它像omg一样运行时,im不在正确的线程中,所以我不能这样做,先生。如何从适当的线程调用游戏中的方法?(是的,我知道代码很难看,有神奇的数字,但我只是在不费吹灰之力的情况下把它处理掉了。是的,我没有编程游戏的经验)

    public partial class Game : Grid
    {
        public bool running;
        public Paddle p;
        public Ball b;
        Timer t;
    
        public Game()
        {
            Width = 500;
            Height = 400;
            t = new Timer(20);
            p = new Paddle();
            b = new Ball();
            for (int i = 15; i < 300; i += 15)
            {
                for (int j = 15; j < 455; j += 30)
                {
                    Brick br = new Brick();
                    br.Margin = new Thickness(j, i, j + 30, i + 15);
                    Children.Add(br);
                }
            }
            Children.Add(p);
            Children.Add(b);
            p.Focus();
            t.AutoReset = true;
            t.Start();
            t.Elapsed += new ElapsedEventHandler(t_Elapsed);
        }
    
        void t_Elapsed(object sender, ElapsedEventArgs e)
        {
            if (running)
            {
                Update();
            }
        }
    
        void Update()
        {
            b.Update(); //Error here when Update is called from t_Elapsed event
        }
    
        void Begin()
        {
            running = true;
            b.Initiate();
        }
    }
    
    3 回复  |  直到 10 年前
        1
  •  12
  •   luke    16 年前

    你应该使用 DispatcherTimer 相反,它将确保计时器事件发布到正确的线程。

        2
  •  5
  •   Ed Power    10 年前

    计时器已用事件在线程池中的线程上激发( http://www.albahari.com/threading/part3.aspx#_Timers )而不是在UI线程上。最好的方法是通过如下调用调用调用控件的调度程序:

    yourControl.Dispatcher.BeginInvoke(
       System.Windows.Threading.DispatcherPriority.Normal
       , new System.Windows.Threading.DispatcherOperationCallback(delegate
       {
            // update your control here
    
            return null;
       }), null);
    
        3
  •  0
  •   Community Mohan Dere    9 年前

    The calling thread cannot access this object because a different thread owns it

    this.Dispatcher.Invoke((Action)(() =>
    {
        ...// your code here.
    }));