当您使用将在程序的整个生命周期内运行的Timer 或Thread 时,您是否需要保留对它们的引用以防止它们被收集垃圾?
请撇开下面的程序可以将 timer 作为类中的静态变量这一事实,这只是一个演示问题的玩具示例。
public class Program
{
static void Main(string[] args)
{
CreateTimer();
Console.ReadLine();
}
private static void CreateTimer()
{
var program = new Program();
var timer = new Timer();
timer.Elapsed += program.TimerElapsed;
timer.Interval = 30000;
timer.AutoReset = false;
timer.Enabled = true;
}
private void TimerElapsed(object sender, ElapsedEventArgs e)
{
var timerCast = (Timer)sender;
Console.WriteLine("Timer fired at in thread {0}", GetCurrentThreadId());
timerCast.Enabled = true;
}
~Program()
{
Console.WriteLine("Program Finalized");
}
[DllImport("kernel32.dll")]
static extern uint GetCurrentThreadId();
}
可以在上面的示例中收集计时器吗?我运行了一段时间,没有出现异常,也没有消息说 ~Program() 被调用了。
更新:我从 this question 中发现( thanks sethcran ) 线程由 CLR 跟踪,但我仍然想要有关计时器的答案。
最佳答案
这只是 System.Threading.Timer 类的一个问题,如果您不以其他方式在某处存储对它的引用的话。它有几个构造函数重载,采用state 对象的那些很重要。 CLR 关注那个状态对象。只要它在某处被引用,CLR 就会将计时器保留在其计时器队列中,并且计时器对象不会被垃圾回收。大多数程序员不会使用那个状态对象,MSDN 文章当然没有解释它的作用。
System.Timers.Timer 是 System.Threading.Timer 类的包装器,使其更易于使用。特别是,只要启用计时器,它将使用该状态对象并保留对它的引用。
请注意,在您的情况下,计时器的 Enabled 属性在进入您的 Elapsed 事件处理程序时为 false,因为您设置了 AutoReset = false。因此,计时器一进入您的事件处理程序就符合收集条件。但是您可以通过引用 sender 参数来避免麻烦,该参数需要将 Enabled 设置回 true。这使得抖动报告成为引用,因此您没有问题。
请务必小心 Elapsed 事件处理程序。该方法内抛出的任何异常都将在没有诊断的情况下被吞噬。这也意味着您不会将 Enabled 设置回 true。您必须使用 try/catch 来做一些合理的事情。如果你不打算有意结束你的程序,至少你需要让你的主程序知道某些东西不再工作了。将 Enabled = true 放在 finally 子句中可以避免收集计时器垃圾,但有让您的程序一遍又一遍地抛出异常的风险。
关于c# - 定时器可以自动收集垃圾吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18136735/
类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
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
使用带有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
我发现ActiveRecord::Base.transaction在复杂方法中非常有效。我想知道是否可以在如下事务中从AWSS3上传/删除文件:S3Object.transactiondo#writeintofiles#raiseanexceptionend引发异常后,每个操作都应在S3上回滚。S3Object这可能吗?? 最佳答案 虽然S3API具有批量删除功能,但它不支持事务,因为每个删除操作都可以独立于其他操作成功/失败。该API不提供任何批量上传功能(通过PUT或POST),因此每个上传操作都是通过一个独立的API调用完成的
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
我正在阅读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方法
我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI
如何在ruby中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL
我喜欢使用Textile或Markdown为我的项目编写自述文件,但是当我生成RDoc时,自述文件被解释为RDoc并且看起来非常糟糕。有没有办法让RDoc通过RedCloth或BlueCloth而不是它自己的格式化程序运行文件?它可以配置为自动检测文件后缀的格式吗?(例如README.textile通过RedCloth运行,但README.mdown通过BlueCloth运行) 最佳答案 使用YARD直接代替RDoc将允许您包含Textile或Markdown文件,只要它们的文件后缀是合理的。我经常使用类似于以下Rake任务的东西: