在我们的.NET 4.0 Winforms应用程序中,当应用程序使用此代码保存其设置时,一些用户(所有Win7 x64)最近经历了非常长的等待时间(与其他用户相比):
Properties.Settings.Default.Save();
应用程序设置(范围:用户,保存在AppData \ Local \\下的user.config中的所有内容)包含多个自定义类以及两个表示打印机设置的类: System.Drawing.Printing.PageSettings和 System.Drawing.Printing.PrinterSettings
在其中一台机器上使用GlowCode探查器,我发现以下功能需要17秒:
<Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterPrinterSettings_x003A__x003A_Write9_PrinterSettings Nodes="1" Visits="1" percent_in_Child="100.00 %" Time_in_Child="17.456" Time="17.456" Avg._Time_in_Child_="17.456" Avg._Time="17.456" Blocks_net="12" Bytes_net="1024" Blocks_gross="1087" Bytes_gross="494146" />
其中持续时间几乎平均分为三个getter(取自GlowCode查看器):
进行一些研究后发现: https://social.msdn.microsoft.com/Forums/vstudio/en-US/8fd2132a-63e8-498e-ab27-d95cdb45ba87/printersettings-are-very-slow 和 http://www.pcreview.co.uk/forums/papersources-and-papersizes-really-slow-some-systems-t3660593.html,引用:
在某些系统上,特别是Vista x64系统,它需要永远(5到15 如果为x64编译,则为秒,如果为x86编译,则为10-20秒,以进行枚举 无论是纸张来源还是纸张化打印机对象的集合。
使用一个小型测试应用程序只需保存PrinterSettings就可以在其中一台“慢速”机器上节省大约3.5秒的时间,而另一台则对0.2秒的持续时间没有留下深刻印象,这与我的快速开发机器相对应。
关于原因和如何改进的任何想法?
如何找到这些延误的真正原因?
编辑:感谢您指出通过驱动程序获取打印机设置,这可能会解释某些计算机上的延迟。
在将来无论何时安装我无法访问的计算机上更新打印机驱动程序是不可能的。
另外,我不会(我知道我知道)减少要保存的PrinterSettings信息,因为有些人可能会遇到滞后并最终破坏向后兼容性......
也许如果我在后台尝试序列化(在用户完成一些打印机更改后?),它可能会加速......
答案 0 :(得分:1)
第一个建议:
检索纸张来源和纸张尺寸的调用正在传递给驱动程序。最好的办法是确保安装了最新版本的驱动程序。有可能旧版本的驱动程序(特别是来自CD中的那些驱动程序)是旧的和错误的。如果您还没有,请访问制造商的网站,并获取最新信息。
第二个建议
除此之外,这将是一个痛苦,但您可以尝试使用底层的Win32 API而不是CLR对应的API。在这种情况下,您需要调用GetPrinter,请求PRINTER_INFO_2结构。完成后,您可以检查pDevMode以获取具有您正在查找的所有信息的DEVMODE结构。
This question或this question应该会有所帮助。
只保留单个设置作为其基本类型,而不是持久化整个PrinterSettings类实例。保持简单 - 字符串,整数,布尔等。显然,Serializer正在请求与打印机进行通信,这就是引入延迟的原因。我愿意打赌,如果你抓住个别班级成员并自行序列化,你会看到改进。
显然,这意味着当您加载设置时,您需要将所有这些设置反序列化为新的PrinterSettings类,然后应用它们。
编辑1,回答问题编辑
这是真的 - 您可以在后台运行Save()
异步。您唯一的问题是,如果用户在保存完成之前尝试结束该过程(关闭应用程序)。你必须保持一个关于是否正在进行保存的bool(在回调触发时设置为false)。如果用户试图退出应用程序并且bool为true,请设置“请等待设置保存...”,直到bool变为false。
答案 1 :(得分:0)
因此,似乎有些机器需要很长时间才能通过已安装的驱动程序查询页面和打印机设置。我无法找到关于此的细节。
为了缩短关机时间,在用户更改打印机设置后,上述部分设置在后台线程中分配并保存。大约需要10秒钟。
在关机期间(表单关闭),这些设置再次 分配,但我们仍然保存所有设置(使用Properties.Settings.Default.Save())并且不知何故,序列化程序会识别出他们没有&#39 ; t对查询进行了更改,因此保存很快完成:
在0.02到0.05秒之间,但仍然可以正确保存所有设置!
有趣的事实:这个问题是在我们购买新的办公室打印机的那一周首次报道的:)