开发者

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

So I am making a simple brick breaking game in c#/wpf. I am running into an issue using timers, I feel like it is probably a simple fix but here is whats happening. Whenever t_Elapsed is fired it attempts to call Update() but when it does its like OMG Im not in the right thread so I cant do that sir. How do I invoke the method from the Game from the proper thread? (And yes I know the code is ugly and has magic numbers but I just kinda chugged it out without putting a lot of eff开发者_运维百科ort in. And yes I have zero experience programming games)

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();
    }
}


You should use the DispatcherTimer object instead, it will ensure that the timer events are published to the correct thread.


Timer elapsed events fire on a thread from the thread pool (http://www.albahari.com/threading/part3.aspx#_Timers) and not on the UI thread. Your best approach is to invoke the control's dispatcher through a call like this:

yourControl.Dispatcher.BeginInvoke(
   System.Windows.Threading.DispatcherPriority.Normal
   , new System.Windows.Threading.DispatcherOperationCallback(delegate
   {
        // update your control here

        return null;
   }), null);


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

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜