添加了 {APPTYPE CONSOLE} 指令,现在我的应用程序运行速度非常慢。 移动鼠标使其运行速度更快
我正在尝试扩展第 3 方应用程序,以便除了使用 Windows 窗体 GUI(需要混合模式)之外,还可以通过命令行调用它。 这是一个相当简单的程序,基本上加载一个文件,然后单击一个按钮,它开始发送 UDP 网络数据包。
我需要从另一个应用程序调用该应用程序,并希望传递一个参数,并且需要能够将 ExitCode 返回到调用应用程序。 根据我的阅读,为了做到这一点,您需要添加编译器指令 {APPTYPE CONSOLE}。
我这样做了,我的应用程序按照我想要的方式工作,除了发送网络数据包的速度减慢了。 我发现每当我在表单上移动鼠标时都会出现这种情况。 表明网络传输速率显着提高。 我怀疑存在某种类型的 Windows 消息队列问题,并且移动鼠标会导致中断,进而导致消息队列被处理?
我已经用 google 搜索并尝试在计时器中使用1ms 间隔,这根本没有帮助。 我在这个 其他应用程序的用户手册中发现,它说 Indy 10 支持APPTYPE CONSOLE 和 GUI 类型。 坦率地说,这让我感到困惑,因为我认为所有网络库都可以在两种模式下工作......但就像我说的,我不熟悉 Delphi。
我确信问题仅限于我的应用程序中的一行,即是否包含 {APPTYPE CONSOLE}。
有人有任何想法吗?
版本信息:
Delphi 7 个人版(内部版本 4.453)
印地9.0.4
I am trying to extend a 3rd party application so that it can be invoked via command line in addition to using the windows form GUI (mixed mode is desired). It's a fairly simple program which basically loads a file and then you click a button it starts sending UDP network packets.
I need to invoke the application from another and would like to pass in an argument and need to be able to return the ExitCode to the calling app. From what i've read, in order to do so you need to add the compiler directive {APPTYPE CONSOLE}.
I did this and my application worked as I wanted it to except sending the network packets slowed down to a crawl. I found that whenever I moved my mouse around on the form. That the network transfer rate increased significantly. I suspect there is some type of Windows Message queue problem and moving mouse is causing interrupts which in turn is causing the message queue to be processed?
I have googled around and tried calling Application.ProcessMessages and PeekMessages in a Timer with a 1ms interval and that didn't help at all. I found in this user manual for some other application it says that Indy 10 is supported in both APPTYPE CONSOLE and GUI types. Quite frankly this just confuses me as I would have assumed that all network library would work in both modes... but like I said I'm not familiar with Delphi.
I am positive that the issue is isolated to a single line in my application and that is whether or not {APPTYPE CONSOLE} is included or not.
Anyone have any ideas?
Version Info:
Delphi 7 Personal (Build 4.453)
Indy 9.0.4
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
如果您将
{APPTYPE CONSOLE}
添加到您的应用程序,即使您希望混合模式执行,那么即使应用程序处于 GUI 模式,您也必须使用控制台。 你当然可以关闭控制台,但这会导致一些闪烁,对我来说有点黑客行为。您应该能够在没有控制台程序的情况下做您想做的事情。 一个小测试程序证明退出代码可以从 GUI 程序中读取:
如果使用以下 cmd 文件执行:
程序显示其主窗体 1 秒,关闭,脚本将 42 打印到控制台窗口。
现在捕获输出 - 如果允许使用临时文件,从 GUI 程序执行此操作实际上比从控制台程序执行此操作更容易。 无论如何,您都需要使用命令行参数来启动程序,那么为什么不给它一个临时文件的名称,等待应用程序完成,读入该文件并随后将其删除呢?
If you add
{APPTYPE CONSOLE}
to your application even though you desire mixed mode execution, then you will have to live with a console even when the application is in GUI mode. You can of course close the console, but this will cause some flicker and feels a bit hackish to me.You should be able to do what you want without a console program. A small test program proves that the exit code can be read from a GUI program:
If this is executed with the following cmd file:
the program shows its main form for 1 second, closes, and the script prints 42 to the console window.
Now for capturing the output - doing this from a GUI program is actually easier than doing it from a console program, if you allow for the use of a temporary file. You need to start the program with a command line parameter anyway, so why not give it the name of a temporary file, wait for the application to finish, read in the file and delete it afterwards?
如果您希望应用程序返回“错误”代码,则无需将其设为控制台应用程序。 你只需要设置ExitCode,例如
在批处理文件中
就会显示应用程序,然后显示10时。
注意:还可以使用 AllocConsole 从 Windows API 动态创建控制台窗口,或使用 AttachConsole 进行附加。
我为此创建了一个对象包装器,但不再有可用的代码。 从记忆中它不支持重定向(因为我不需要它)。
If you want an application to return an "error" code there is no need to make it a console application. You only need to set the ExitCode, e.g.
in a batch file
Will display the application, then display 10 when.
Note: It is also possible to create a console window dynamically from the windows API using AllocConsole or to attach using AttachConsole.
I created an object wrapper for this once, but no longer have the code available. From memory it didn't support redirection (because I didn't need it).
如果我理解正确,那么您希望您的应用程序有两种模式:
最简单的是如果您可以集中逻辑,以便可以从一种方法调用它(在我的示例中为 CoreLogic)。
下面的应用程序应该可以正常工作。
两个技巧:
一些注意事项:
希望这可以帮助 :-)
If I understand you correctly, then you want your app to have two modes:
The easiest is if you can centralize your logic so it can be called from one method (CoreLogic in my example).
The below app then should work fine.
Two tricks:
A few notes:
Hope this helps :-)
1 毫秒的计时器大约每 40 毫秒触发一次(由于 Windows 限制),所以它没有帮助。 我已经看到了像你描述的混合控制台和 GUI 应用程序的效果,另一个是它们没有正确最小化。
您可以使用 CreateConsole API 调用(不确定名称是否正确)在程序启动后创建一个控制台,而不是在项目中启用控制台。 我在我执行此操作的一个(!)程序中没有看到任何不利影响。
但这仅当您想写入控制台时才需要。 如果您只想处理命令行参数并返回退出代码,则不需要控制台。 只需评估 ParamCount/ParamStr 函数的参数并设置 ExitCode 作为返回值即可。
A timer with 1ms will only fire about every 40 ms (due to Windows limitations), so it won't help. I have seen effects like you describe with mixed console and GUI apps, another is that they don't minimize properly.
Instead of enabling the console in the project, you could probably use the CreateConsole API call (Not sure whether the name is correct) to create one after the programm was started. I have seen no adverse effects in the one (!) program I have done this.
But this is only necessary if you want to write to the console. If you only want to process command line parameters and return an exit code, you do not need a console. Just evaluate the ParamCount/ParamStr functions for the parameters and set ExitCode for the return value.
如果您的控制台应用程序中的某些线程调用 Synchronize(我猜 Indy 的东西实际上就是这样做的),您必须做一些准备:
将一个方法分配给 WakeMainThread 变量。 该方法必须具有 TNotifyEvent 的签名。
在此方法中调用CheckSynchronize。
有关其他信息,请参阅这两项的 Delphi 帮助。
If some threads in your console application call Synchronize (and I guess the Indy stuff is actually doing that), you have to make some preparations:
Assign a method to the WakeMainThread variable. This method must have the signature of TNotifyEvent.
Inside this method call CheckSynchronize.
For additional information see the Delphi help for these two items.