Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 不使用新线程打开大型查询_Multithreading_Delphi_Delphi Xe - Fatal编程技术网

Multithreading 不使用新线程打开大型查询

Multithreading 不使用新线程打开大型查询,multithreading,delphi,delphi-xe,Multithreading,Delphi,Delphi Xe,我有一个大查询需要加载到内存中。打开此查询大约需要30秒。它在应用程序启动后立即加载,仅加载一次。在此期间,应用程序挂起。我需要做的是在30秒内更新进度条。我试图创建一个新线程来更新进度条,但它只会在查询打开后更新。有人能指出一个简单的方法来做到这一点吗 我创建了一个线程类: type TMyThread = class(TThread) private fLowerLimit: Integer; fUpperLimit: Integer; Count

我有一个大查询需要加载到内存中。打开此查询大约需要30秒。它在应用程序启动后立即加载,仅加载一次。在此期间,应用程序挂起。我需要做的是在30秒内更新进度条。我试图创建一个新线程来更新进度条,但它只会在查询打开后更新。有人能指出一个简单的方法来做到这一点吗

我创建了一个线程类:

type
   TMyThread = class(TThread)
   private
      fLowerLimit: Integer;
      fUpperLimit: Integer;
   CountingThread := TMyThread.Create(0, 300, True);
   CountingThread.Resume;
   //
   SplashDlg.Show;
我正在创建thread类的一个实例:

type
   TMyThread = class(TThread)
   private
      fLowerLimit: Integer;
      fUpperLimit: Integer;
   CountingThread := TMyThread.Create(0, 300, True);
   CountingThread.Resume;
   //
   SplashDlg.Show;
在线程内部,我只是更新进度条:

procedure TMyThread.UpdateMainThread;
begin
   SplashDlg.ProgressBar1.Position:= SplashDlg.ProgressBar1.Position+1;
   MyDebug('UpdateMainThread:'+ IntToStr(SplashDlg.ProgressBar1.Position));
end;

查询打开时线程挂起。

如果希望得到更准确的答案,最好在此处粘贴一些代码

有两种方法可以处理数据并使UI响应

  • 您可以在循环中使用Application.ProcessMessages

  • 或者您已经接近的线程解决方案

问题是我不认为你有一个循环,你正在使用一个组件,如果该组件没有调用一个方法来显示进度,你就无法估计完成查询需要多少时间。所以要么你显示一个加载。。。屏幕,而te查询在没有进度条的情况下执行,或者您可以告诉我们有关查询所用内容的更多信息


希望能有所帮助

你的做法正好相反

UI绑定到应用程序主线程,因此您必须始终在主线程中维护UI,并在工作线程中执行真正的工作(从那里输入工作线程名称)

你问这个问题的方式是,你已经在处理线程了,所以,只要改变你的观点,在次要线程中执行繁重的SQL负载,同时保持你的UI在现在不忙的主线程中响应和更新

至于30秒的等待时间,真的,如果你不能准确确定加载时间,最好不要使用进度条,因为我们都讨厌那些不能反映事物真实状态的撒谎条。你的酒吧有时会显示50%,然后突然变成100%。。。或者,它可能达到100%,而事实上,真正的事情需要很长时间才能完成(服务器负载重,网络速度慢,以及1000个其他因素)

如今,我们都习惯了等待指示灯,如下所示:


当您看到这一点时,您就知道它正在工作,您只需等待它完成即可。

您好。我使用的是一个组件,因此进程显示和Application.ProcessMessages将被删除。我已经显示了一个启动屏幕,我只需要放置一个进度条并显示估计30秒的进度。我正在用线程代码更新帖子。谢谢这是一个TUniQuery(Devart)组件。永远不要提倡使用Application.Processmessages!!!虽然TUniQuery似乎不支持AsyncFetch作为Ado,但似乎有一个非阻塞选项可能会有所帮助。无法从线程更新GUI。您需要将数据库读取移动到自己的线程,然后使用计时器更新进度条。您的做法是相反的。始终注意主线程中的UI,并在辅助线程中完成真正的工作。为什么不想使用线程打开查询?你已经在处理线程了@贾斯盖特:谢谢。将此作为答案发布。