Dan*_*axa 0 delphi indy apache-synapse
将网页源下载到备忘录组件的最快方法是什么?我使用Indy和HttpCli组件.
问题是我有一个填充了100多个站点的列表框,我的程序将源代码下载到备忘录并解析该源文件的mp3文件.它类似于谷歌音乐搜索程序; 它使用Google查询来简化Google搜索.
我开始阅读导致我的问题的线程:我可以在具有解析功能的线程中创建一个IdHttp实例并告诉它解析列表框中的一半网站吗?
所以基本上当用户点击解析时,主线程应该这样做:
for i := 0 to listbox1.items.count div 2 do
get and parse
Run Code Online (Sandbox Code Playgroud)
,另一个线程应该做:
for i := form1.listbox1.items.count div 2 to form1.listbox1.items.count - 1 do
get and parse.
Run Code Online (Sandbox Code Playgroud)
,所以他们会form1.listbox2在同一时间添加解析的内容.或者在主线程中启动两个IdHttp实例可能更容易; 一个是上半部分,另一个是第二个?
为此:我应该使用Indy还是Synapse?
我会创建一个可以读取单个URL并处理其内容的线程.然后,您可以决定要同时触发的线程数量.您的计算机将允许相当多的连接,因此如果这100个站点具有不同的主机名,则同时运行10或20不是问题.太多是过度杀伤,但是太少是浪费处理器时间.
您可以通过单独的线程进行下载和处理来进一步调整此过程,以便您可以让许多线程不断下载内容.下载不是处理器密集型的.它基本上等待响应,因此您可以轻松拥有相对大量的下载线程,而其他几个工作线程可以从结果池中获取项目并处理它们.
但拆分下载和处理会使它变得有点复杂,我认为你还没有接受这个挑战.
因为目前,你还有其他一些问题.首先,在线程中不使用VCL组件.如果您需要线程中列表框中的信息,则需要在线程中使用Synchronize来对主线程进行"安全"调用,否则您必须在启动线程之前传递所需的信息.后者更有效,因为使用Synchronize执行的代码实际上在主线程中运行,使您的多线程效率降低.
但我的注意力实际上是第一行," 将网页源下载到备忘录组件 ".不要那样做!请勿将这些结果加载到备忘录中进行处理.自动处理最好在内存中,在可视控件之外完成.使用字符串,流甚至字符串列表来处理文本比使用备忘录更快.
stringlist也有一些开销,但它使用相同的索引结构(TMemoStrings,它是Memo的Lines属性,而TStringList都具有相同的祖先),所以如果你有使用它的代码,将它转换为TStringList非常容易.
我建议在线程中进行所有解析,不要让主线程做任何解析.主线程应该只管理UI.不要从TMemo解析HTML,让每个线程下载到TStream或String,然后直接解析.使用TIdSync或TIdNotify将解析结果发送到UI进行显示(如果速度很重要,请使用TIdNotify).在解析逻辑中使用UI组件会降低它的速度.