2015-09-03 4 views
0

В приложении wpf есть холст, который я передаю в класс Game. В моем gameclass я хочу обновить холст каждые 0,02 секунды. На данный момент мой код работает, но он чувствует себя «Hacky», мой код:C# update canvas in while loop

public void Start() 
{ 

    bw = new BackgroundWorker(); 
    bw.DoWork += bw_DoWork; 
    bw.ProgressChanged += bw_ProgressChanged; 
    bw.WorkerReportsProgress = true; 
    bw.RunWorkerAsync(); 
} 

void bw_ProgressChanged(object sender, ProgressChangedEventArgs e) 
{ 
    GameRender(); 
} 

void bw_DoWork(object sender, DoWorkEventArgs e) 
{ 
    while (Running) 
    { 
     GameUpdate(); 
     //GameRender(); 
     bw.ReportProgress(1);   
     //repaint(); 
     try 
     { 
      Thread.Sleep(10); 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine(ex + ""); 
     } 
    } 
} 

Потому что кажется, как взломать ко мне, я попытался с помощью тему, как;

public void Start() 
    { 

     new Thread(() => 
     { 
      while (true) 
      { 
       GameUpdate(); 
       GameRender(); 
      } 
     }).Start(); 
    } 

Но это сбой в моем GameRender(), где я пытаюсь обновить свой холст. Ошибка:

An unhandled exception of type 'System.InvalidOperationException' occurred in WindowsBase.dll 

Как обновить холст от класса?

+0

Его нет в потоке пользовательского интерфейса, поэтому он выдает недействительную операцию. Для операций пользовательского интерфейса попробуйте использовать Application.Current.Dispatcher.BeginInvoke ( DispatcherPriority.Background, new Action (() => { // обновлять ресурсы пользовательского интерфейса })); –

+0

@sumeetkumar, как я мог применить его в цикле и запускать его каждые 0,20 секунды. –

+0

Как в стороне, работа со скоростью 50 кадров в секунду с таймерами с запасом окон будет ненадежной - лучшее разрешение, которое вы, как правило, получаете, составляет ~ 15 мс. Более высокое разрешение может привести к смерти ноутбука. См. [Почему таймеры .NET ограничены разрешением 15 мс?] (Http://stackoverflow.com/q/3744032/156755) и [Как использовать Таймер высокого разрешения] (https://msdn.microsoft. com/en-us/library/aa964692% 28v = vs.85% 29.aspx? f = 255 & MSPPError = -2147217396) – Basic

ответ

0

Используйте событие CompositionTarget.Rendering, чтобы обновить управление Canvas. Это событие запускается каждый раз, когда WPF создает фрейм. Это более традиционный метод обновления вашего интерфейса в цикле.

CompositionTarget.Rendering += DoUpdates; 

private void DoUpdates(object sender, EventArgs e) 
{ 
    // Update canvas 
} 
+0

'Это более традиционный метод обновления вашего интерфейса на цикле' - что, конечно, мы не хотим. Манипулирование визуальным деревом внутри этого события не рекомендуется, поэтому я действительно не вижу, к чему ведет ваш ответ ... –

+1

Можете ли вы предоставить ссылку на какой-либо ресурс, который рекомендует не манипулировать визуальным деревом из этого события? –

+0

Вы можете указать ссылку на какой-либо ресурс, который рекомендует это делать? –