GDI+像地图一样加载数据时绘制

发布于 2024-10-28 00:16:49 字数 885 浏览 1 评论 0原文

我有一个应用程序可以找到 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:

namespace PathFinder
{

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

  public Generate()
  {
     //lots of loops
  }
}

I have an application that finds the shortest path between 2 squares, and when the path is longer or more complicate it can take 1-2 seconds to find it and I want to write on the screen a loading message that changes (first "Loading" then "Loading." then "Loading.." etc.).

Another problem is that the application give a "Not Responding" message if it take longer (10-12 seconds) how can I get rid of this?

The code so far:

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:

namespace PathFinder
{

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

  public Generate()
  {
     //lots of loops
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

笛声青案梦长安 2024-11-04 00:16:49

原因是 UI 主线程必须处理事件。
如果一段时间内没有,它就会开始抱怨,这就是你所经历的。

因此,您不应该通过任何冗长的处理来阻塞 UI 线程。

使用 BackgroundWorker 类 进行此类操作。

如果您选择在 UI 线程中进行处理,另一种选择(不推荐)是

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

在漫长的操作周期之间使用。

The reason for this is that UI main thread must process events.
If it does not for a period, it starts complaining, that is what you are experiencing.

So, you should not block the UI thread with any lengthy processing.

Use the BackgroundWorker Class for such operations.

Another option (not recommended) would be using

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

in-between the lengthy operation cycles, if you choose to do processing in the UI thread.

瑶笙 2024-11-04 00:16:49

使用BackgroundWorker 卸载工作线程上长时间运行的计算。这可以防止 UI 冻结。 MSDN 库详细介绍了 BGW,请务必遵循示例。

然而,您必须执行的任何绘图仍然需要通过 Paint 事件在 UI 线程上完成。只要确保您可以尽快完成即可。让工作人员将路径存储在 Point[] 或 GraphicsPath 中。在 BGW 的 RunWorkerCompleted 事件处理程序中调用 Invalidate() 来运行绘制事件。

Use a BackgroundWorker to offload long-running calculations on a worker thread. That prevents the UI from freezing. BGW is well covered by the MSDN Library, be sure to follow the examples.

Any drawing you have to do however still needs to be done on the UI thread with the Paint event. Just make sure that you can do so as quickly as possible. Have the worker store the path in, say, a Point[] or a GraphicsPath. Call Invalidate() in the BGW's RunWorkerCompleted event handler to get the paint event to run.

醉城メ夜风 2024-11-04 00:16:49

查看您的代码可能会有所帮助。为了避免窗口停止,您可以使用单独的线程进行计算,或者在您的进程中,如果winform,您可以使用Applications.DoEvents();
正如我所说。

嗯,这有效吗?

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

Seeing your code might help.To avoid window to halt you may use seperate thread for calculations or in your process you may use Applications.DoEvents(); if winform.
As i said.

Well Does this works?

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();
   }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文