在C#中应用的最佳线程实践,用于懒惰地卸载动态创建的多个AppDomain

时间:2015-05-21 21:08:00

标签: c# multithreading background task lazy-evaluation

考虑拥有一个创建30个app-domains的应用程序,然后运行它们(每个app-domain在自己的线程中),当这些app-domains中的每一个完成运行时(也就是它的线程退出等等)我们需要清理通过为每个appdomain运行一些自定义清理逻辑+一个用于卸载appdomain本身的调用。

每个app-domains的清理逻辑+ appdomain-unloading调用可能需要多次尝试才能成功(由于涉及资源,需要时间由系统释放等等上)。如果无法在特定的尝试中执行清理操作,我们需要花费超过100毫秒的时间才能知道并继续进行。

在C#世界中,以“执行 - 清除后台”方式执行此类清理的最佳做法是什么?可能的场地是我的头顶:

  1. 每个app-domain清理应该在它自己的'new Thread()'角落中执行。如果需要重试,每个线程都会在while循环中保持休眠状态。

  2. 只有一个专用的长期运行线程,其中包含一个任务队列,我们​​在其中提交要清理和卸载的每个应用程序域(再次以类似于上面方法#1的持久方式)。

  3. 使用线程池并在那里提交清理任务

  4. 根据以下评论:

    https://stackoverflow.com/a/28651533/863651

    “如果一个方法不能在开始执行的100ms左右退出,那么该方法应该通过主线程池以外的其他方式执行。[...]但是,如果方法需要要执行的第二个或更长时间,并且将大部分时间用于阻止,该方法应该可以在专用线程中运行,并且几乎肯定不会在主线程池线程中运行。“

    我想这不鼓励使用上面的方法#3。我想知道方法#2是否比方法#1有任何相当大的优势。让我烦恼的主要问题是,即使方法#2需要稍微多一点的编码,它也只使用1个线程,而方法#2将需要N个线程用于N个应用程序域(这需要所有成本)产生线程等)。

    我愿意接受有关可能实现此类机制的任何方法#4 +的建议。我很想知道其他程序员在遇到这样的问题时如何应用“最佳线程实践”的概念。

    提前致谢。

    P.S。:此应用程序适用于当代台式计算机(在撰写本文时)。

1 个答案:

答案 0 :(得分:1)

假设您知道在管理AppDomain时需要清理的内容,您可以将清理逻辑附加到DomainUnload事件,如:

appDomain.DomainUnload += 
  (sender, args) => 
  {
       //this logic needs to be specific for each AppDomain.

       //you can consider using a class like BackgroundWorker to do the work.

  };

对于单线程和多线程问题,只要你使代码线程安全,那么我的看法是多线程选项既减少了代码行(总是我的目标)又优化了性能,特别是如果将清理作为后台线程运行。就挖掘系统资源而言,10个线程实际上不是问题(除非清理操作可能耗尽内存)。主要的缺点是多线程程序有时候调试起来比较棘手,但我敢打赌,在这种情况下你会没事的。