C# 如何在新线程中启动包含计时器的对象?
如何开始在新线程中运行包含计时器的对象 我有下面的代码,我可能应该更改它:C# 如何在新线程中启动包含计时器的对象?,c#,multithreading,timer,garbage-collection,C#,Multithreading,Timer,Garbage Collection,如何开始在新线程中运行包含计时器的对象 我有下面的代码,我可能应该更改它: class MemoryCleaner : IDisposable { private readonly static MemoryCleaner Instance = new MemoryCleaner(); private readonly Timer _memoryWatcher = new Timer(15 * 1000); public Tim
class MemoryCleaner : IDisposable
{
private readonly static MemoryCleaner Instance = new MemoryCleaner();
private readonly Timer _memoryWatcher = new Timer(15 * 1000);
public Timer MemoryWatcher
{
get
{
return this._memoryWatcher;
}
}
public void Dispose()
{
_memoryWatcher.Elapsed -= memoryWatcher_Elapsed;
this._memoryWatcher.Stop();
}
private void memoryWatcher_Elapsed(object sender, ElapsedEventArgs e)
{
var currentProcess = Process.GetCurrentProcess();
var megaBytes = currentProcess.PrivateMemorySize64 / (1024 * 1024);
if (megaBytes > 100)
{
// force an immediate garbage collection to free some unused memory quickly; this is an expensive process!
GC.Collect();
}
}
internal static void Start()
{
// this should be created in a new thread
Instance.MemoryWatcher.Elapsed += Instance.memoryWatcher_Elapsed;
Instance.MemoryWatcher.Start();
GC.KeepAlive(Instance);
}
internal static void Stop()
{
Instance.Dispose();
}
}
我想像这样使用它:
MemoryCleaner.Start();
// my memory thirsty code which generates so much garbage, e.g. downloads a document then disposes it.
MemoryCleaner.Stop();
它应该做的是创建一个新线程,然后在该线程上创建MemoryCleaner对象的新实例并启动该对象
那怎么可能做到呢
一些背景信息:
基本上,代码应该做的是每15秒检查一次主进程使用的内存,如果内存使用量超过100MB,则强制执行垃圾收集,因为将创建大量垃圾
希望问题清楚
谢谢,如果您正在创建一个
System.Threading.Timer
或System.Timers.Timer
在哪个线程上创建它并不重要-除非您指定一个同步对象,否则计时器将在线程池线程上启动。为什么只为创建部分创建线程
(我不确定所有这些都是一个好主意,但是这是一个单独的问题……你也应该考虑单代码实现是否执行<代码> IDISPOSTABLE <代码>真的是明智的。
如果你的应用程序真的使用了>100MB,每15秒强制一个GC只会让事情变得更糟。通过保持100MB的分页,这与您想要的相反(允许操作系统在不使用时将其分页,从而释放物理RAM)。您不“运行”或“启动”对象。收集超过100MB的垃圾,使GC保持100MB的分页?你什么意思?谢谢你,乔恩。我希望它在单独的线程上运行的原因是,在我的代码中,这个过程不起作用。我不知道为什么。我尝试了一个简单的应用程序,但无法重现这个问题,而且这个过程运行良好。不确定是什么原因导致我的prod应用程序无法运行。@TheLight:我会集中精力诊断差异,而不是将某些内容放在不同的线程上。我的应用程序使用大量多线程,因此如果我可以在单独的线程上完全运行MemoryCleaner(不会与任何其他代码共享)那么它应该解决这个问题。我认为原因是,当计时器过期时,它会等待线程池中至少有一个可用线程,因此它无法找到它,并等待其中一个线程再次可用。@TheLight:启动计时器后,它将启动线程池线程。您可以为此单独启动一个线程(并在GCs之间睡眠),但这是另一回事。我仍然认为,诊断一些本该有效的东西为什么无效是值得的。