我们正在将应用程序迁移到 .NET 4.0(从 3.5)。我们遇到的问题之一只能在非常特定的条件下重现:
我的意思是,如果我禁用优化并且将调试信息设置为完整,问题就会消失。
有问题的代码在 .NET 3.5 上运行良好,在 Release模式下启用了优化等,并且已经完成了很长时间。
我真的不想暗示 C# 编译器中存在错误,所以我的问题是是否有任何技术可以用来追踪我们可能做错了什么导致不正确的优化?
我正在尝试将这个问题缩小到一个小测试用例,以便我可以在此处发布一些代码。
编辑:
我已经追踪到以下问题:
我们在表单的构造函数中有这段代码:
public ConnectionForm()
{
LocalControlUtil.Configure("ConnectionForm", "Username", usernameLabel);
LocalControlUtil.Configure("ConnectionForm", "Password", passwordLabel);
LocalControlUtil.Configure("ConnectionForm", "Domain", domainLabel);
LocalControlUtil.Configure("ConnectionForm", "Cancel", cancelButton);
LocalControlUtil.Configure("ConnectionForm", "OK", okButton);
}
这些调用是针对一些自定义本地化代码的。此窗体的构造函数是从另一个程序集调用的。 LocalControlUtil.Configure 方法调用 Assembly.GetCallingAssembly(),它为上述所有调用返回正确的值,最后一个调用除外。
我可以重新排列上面的行,添加新行或删除当前行,每次都是最后一行不起作用。
我假设这是 JIT 将最后一个方法调用内联到调用构造函数的地方(在另一个程序集中)。将 [MethodImpl(MethodImplOptions.NoInlining)] 添加到上面的构造函数可以解决问题。
有人知道为什么会这样吗?我觉得最后一行只能内联似乎很奇怪。这是 .NET 4.0 中的新行为吗?
编辑 2:
我现在已经将其缩小到尾调用消除,我假设是由 new tail-call stuff in .NET 4 引起的.
在上面的代码中,构造函数中对LocalControlUtil.Configure 的最后一次调用被删除,并放入另一个程序集中的调用方法中。当方法调用 Assembly.GetCallingAssembly 时,我们没有得到正确的程序集。
有什么方法可以阻止编译器(或 JIT 或其他执行此操作的人员)消除尾调用吗?
最佳答案
如果不是太长,我会把它放在评论中,但你试过了吗:
public ConnectionForm()
{
try
{
LocalControlUtil.Configure("ConnectionForm", "Username", usernameLabel);
LocalControlUtil.Configure("ConnectionForm", "Password", passwordLabel);
LocalControlUtil.Configure("ConnectionForm", "Domain", domainLabel);
LocalControlUtil.Configure("ConnectionForm", "Cancel", cancelButton);
LocalControlUtil.Configure("ConnectionForm", "OK", okButton);
}
catch
{
throw;
}
}
抛出任何异常的事实使得这在编写代码方面几乎是一个空更改,但 try-catch 边界通常会阻止编译器和抖动方面的优化。
关于c# - 我可以停止 .NET 4 执行尾调用消除吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5708063/
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代
我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta
查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html
是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou
我发现ActiveRecord::Base.transaction在复杂方法中非常有效。我想知道是否可以在如下事务中从AWSS3上传/删除文件:S3Object.transactiondo#writeintofiles#raiseanexceptionend引发异常后,每个操作都应在S3上回滚。S3Object这可能吗?? 最佳答案 虽然S3API具有批量删除功能,但它不支持事务,因为每个删除操作都可以独立于其他操作成功/失败。该API不提供任何批量上传功能(通过PUT或POST),因此每个上传操作都是通过一个独立的API调用完成的
我遵循了教程http://gettingstartedwithchef.com/,第1章。我的运行list是"run_list":["recipe[apt]","recipe[phpap]"]我的phpapRecipe默认Recipeinclude_recipe"apache2"include_recipe"build-essential"include_recipe"openssl"include_recipe"mysql::client"include_recipe"mysql::server"include_recipe"php"include_recipe"php::modul
我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file
我正在阅读SandiMetz的POODR,并且遇到了一个我不太了解的编码原则。这是代码:classBicycleattr_reader:size,:chain,:tire_sizedefinitialize(args={})@size=args[:size]||1@chain=args[:chain]||2@tire_size=args[:tire_size]||3post_initialize(args)endendclassMountainBike此代码将为其各自的属性输出1,2,3,4,5。我不明白的是查找方法。当一辆山地自行车被实例化时,因为它没有自己的initialize方法