GDI + рисовать при загрузке данных как карта - PullRequest
0 голосов
/ 29 марта 2011

У меня есть приложение, которое находит кратчайший путь между 2 квадратами, и когда путь длиннее или сложнее, его поиск может занять 1-2 секунды, и я хочу вывести на экран сообщение о загрузке, которое изменяется (сначала"Загрузка", затем "Загрузка.", Затем "Загрузка ..." и т. Д.).

Другая проблема заключается в том, что приложение выдает сообщение «Не отвечает», если это занимает больше времени (10–12 секунд). Как мне избавиться от этого?

Код на данный момент:

Form1.cs:

namespace PathFinder
{
   Map map1;
   public Form1()
   {
      map1 = new Map(tileDimension, mapDimension);
      map1.Generate(); //the function that calculate the path
      this.Invalidate();
   }

   private void Form1_Paint(object sender, PaintEventArgs e)
   {
      //drawings
      this.Invalidate();
   }
}

Map.cs:

пространство имен PathFinder {

  public Map(Point tileDim, Point mapDim)
  {
     //Initialization
  }

  public Generate()
  {
     //lots of loops
  }

}

Ответы [ 3 ]

2 голосов
/ 30 марта 2011

Причина в том, что основной поток пользовательского интерфейса должен обрабатывать события. Если это не происходит в течение определенного периода, он начинает жаловаться, вот что вы испытываете.

Таким образом, вы не должны блокировать поток пользовательского интерфейса при длительной обработке.

Используйте BackgroundWorker Class для таких операций.

Другой вариант (не рекомендуется) будет использовать

for...
{
    // ...
    // Some lengthy part of processing, but not as lengthy as the whole thing
    Application.DoEvents();
}

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

1 голос
/ 30 марта 2011

Используйте BackgroundWorker для разгрузки длительных вычислений в рабочем потоке.Это предотвращает зависание пользовательского интерфейса.BGW хорошо описан библиотекой MSDN, обязательно следуйте примерам.

Любой чертеж, который вам нужно сделать, все же необходимо выполнить в потоке пользовательского интерфейса с событием Paint.Просто убедитесь, что вы можете сделать это как можно быстрее.Пусть рабочий сохранит путь, скажем, в Point [] или GraphicsPath.Вызовите Invalidate () в обработчике событий RunWorkerCompleted BGW, чтобы запустить событие рисования.

0 голосов
/ 29 марта 2011

Просмотр вашего кода может помочь. Чтобы избежать остановки окна, вы можете использовать отдельный thread для расчетов или в своем процессе вы можете использовать Applications.DoEvents();, если winform.Как я уже сказал.

Ну, это работает?

namespace PathFinder
{
   Map map1;
 BackgroundWorker GetSomeData = new BackgroundWorker();

   public Form1()
   {
      GetSomeData .DoWork += new DoWorkEventHandler(GetSomeData_DoWork);
      map1 = new Map(tileDimension, mapDimension);
      GetSomeData.RunWorkerAsync();
      this.Invalidate();
   }
 void GetSomeData_DoWork(object sender, DoWorkEventArgs e)
 {
      map1.Generate(); //the function that calculate the path
 }

   private void Form1_Paint(object sender, PaintEventArgs e)
   {
      //drawings
      this.Invalidate();
   }
}
...