Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在新线程中启动包含计时器的对象?_C#_Multithreading_Timer_Garbage Collection - Fatal编程技术网

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之间睡眠),但这是另一回事。我仍然认为,诊断一些本该有效的东西为什么无效是值得的。