递归调用方法(用于对象重用目的)

我有一个相当大的类,其中包含大量字段(10 +),一个巨大的数组(100kb)和一些非托管资源。 让我举例说明

class ResourceIntensiveClass { private object unmaganedResource; //let it be the expensive resource private byte[] buffer = new byte[1024 * 100]; //let it be the huge managed memory private Action OnComplete; private void DoWork(object state) { //do long running task OnComplete(this); //notify callee that task completed so it can reuse same object for another task } public void Start(object dataRequiredForCurrentTask) { ThreadPool.QueueUserWorkItem(DoWork); //initiate long running work } } 

问题是start方法在第10000次迭代后永远不会返回,导致堆栈溢出。 我可以在另一个线程中执行OnComplete委托,让Start方法返回,但是如果你知道的话,它需要使用额外的cpu时间和资源。 那对我来说最好的选择是什么?

是否有理由以递归方式进行计算? 这似乎是一个简单的循环可以解决这个问题,从而避免了对非常深的堆栈的需求。 这种设计似乎特别成问题,因为您依靠main()来设置递归。

递归方法可能会非常快速地失控。 您是否考虑过使用Parallel Linq? 你可以做点什么

(你的数组).AsParallel()。ForAll(item => item.CallMethod());

您还可以查看任务并行库(TPL)

通过任务,您可以定义操作并继续执行任务。

另一方面,Reactive Framework(RX)可以以异步方式处理完整事件。

你在哪里更改taskData的值,以便它的长度可以等于currentTaskIndex ? 由于您分配给数据的任务永远不会改变,因此它们将永远执行…

我猜这个问题来自于使用预增量运算符:

  if(c.CurrentCount < 10000) c.Start(++c.CurrentCount); 

我不确定C#中预增量的语义,也许传递给方法调用的值不是你所期望的。

但是,由于你的Start(int)方法将输入的值分配给this.CurrentCount因为它是第一步,你应该安全地将其替换为:

  if(c.CurrentCount < 10000) c.Start(c.CurrentCount + 1); 

分配给c.CurrentCount两次是没有意义的。

如果使用线程池,我假设您正在保护计数器(c.CurrentCount),否则并发增量将导致更多活动,而不仅仅是10000次执行。

有一个称为ManualResetEvent的简洁工具可以简化您的生活。

在您的类中放置一个ManualResetEvent并添加一个公共OnComplete事件。

声明类时,可以将OnComplete事件连接到代码中的某个位置,或者不将其连接并忽略它。

这将有助于您的自定义类具有更正确的表单。

当你的漫长过程完成时(我猜这是在一个线程中),只需调用ManualResetEvent的Set方法即可。

至于运行long方法,它应该在一个以类似于下面的方式使用ManualResetEvent的线程中:

 private void DoWork(object state) { ManualResetEvent mre = new ManualResetEvent(false); Thread thread1 = new Thread( () => { //do long running task mre.Set(); ); thread1.IsBackground = true; thread1.Name = "Screen Capture"; thread1.Start(); mre.WaitOne(); OnComplete(this); //notify callee that task completed so it can reuse same object for another task }