简体   繁体   English

瘦身同步类是每个AppDomain还是每个进程?

[英]Slim synchronization classes are per AppDomain or per Process?

All articles in Internet says that using Thread.Abort is evil (because synchronization primitives belongs to operating system, and process doesn't terminate yet, and primitives might remain locked after thread aborting). Internet上的所有文章都说使用Thread.Abort是邪恶的(因为同步原语属于操作系统,并且进程尚未终止,并且原语可能在线程中止后保持锁定状态)。 Developers advises to terminate whole processes instead, because operation system will free synchronization primitives when process stops. 开发人员建议终止整个过程,因为操作系统将在进程停止时释放同步原语。

  1. Will AppDomain unloading help, If one will use Slim synchronization primitives? AppDomain卸载帮助,如果一个人将使用Slim同步原语? (With .net 4.0 several new classes have been added relating to threading: ManualResetEventSlim , SemaphoreSlim , ReaderWriterLockSlim ). (使用.net 4.0添加了几个与线程相关的新类: ManualResetEventSlimSemaphoreSlimReaderWriterLockSlim )。

    Documentation says that these primitives can't be used beween different processes, because implementation code of primitives is fully managed. 文档说这些原语不能在不同进程之间使用,因为原语的实现代码是完全管理的。 But I don't understand - will these primitives work through AppDomain border. 但我不明白 - 这些原语是否会通过AppDomain边界工作。 (see Can't set synchronization context when using appdomains ) (请参阅使用appdomains时无法设置同步上下文

  2. If yes, how they do that? 如果是的话,他们是如何做到的? If no, then why documentation omit this limitation? 如果不是,那么为什么文档会省略这个限制?

UPD: All my code is trusted by me, including the code inside the domain which i unload. UPD:我所有的代码都是我信任的,包括我卸载的域内的代码。 I don't want to leave the thread working, when the time comes to terminate it. 当终止它时,我不想让线程工作。 I want to terminate (abort) thread instead of "setting flag" and "making nice architecture". 我想终止(中止)线程而不是“设置标志”和“制作漂亮的架构”。 If it is neccessary to create additional thread first (i think this is necessary at start of background processing in separate domain to create one more thread), i will do. 如果首先创建额外的线程是必要的(我认为这是在单独的域中开始后台处理以创建一个更多的线程时所必需的),我会这样做。 I don't want to use "setting flag" approach, because it requires me to instrument background algorithm with flag checks, i shouldn't, it's the runtime or compiler should automate that instrumentation for me. 我不想使用“设置标志”方法,因为它要求我使用标志检查来设置后台算法,我不应该,它是运行时或编译器应该为我自动化该仪器。 Right now there is no such instrumentation, that is why I am trying to apply the approach with domain unloading. 现在没有这样的工具,这就是为什么我试图通过域卸载来应用这种方法。

Adding checks between each instruction (or in deep nested cycles) will slow the code significantly. 在每条指令之间(或在深嵌套循环中)添加检查将显着减慢代码。 Adding check in random locations will not give guaranties of prompt termination. 在随机位置添加检查不会保证提示终止。 If difficulties of writing abort-safe code can be solved, why not to try to abort threads and unload domain? 如果可以解决编写中止安全代码的困难,为什么不尝试中止线程并卸载域?

You misunderstands the AppDomain , Process and Thread definitions - AppDomains always lives in one process, but one process can be a master for different AppDomains *: 您误解了AppDomainProcessThread定义 - AppDomains始终位于一个进程中,但一个进程可以是不同AppDomains * 的主进程

The ability to run multiple applications within a single process dramatically increases server scalability. 在单个进程中运行多个应用程序的能力大大提高了服务器的可伸缩性。

  • this is similar for the Thread , just for mention. 这与Thread相似,仅仅是为了提及。

So, the answer for your question is Yes , the slim synchronization primitives will work with various AppDomains , as there are no cross-process calls in such architecture, only a logical distinction for various processes. 因此,您的问题的答案是肯定的苗条同步原语将适用于各种AppDomains ,因为在这种体系结构中没有跨进程调用,只是各种进程的逻辑区别。

As for the linked question, there are no problem with synchronization primitives there, only with SynchronizationContext , which is Thread -specific , but not AppDomain -specific. 至于链接的问题,那里的同步原语没有问题,只有SynchronizationContext ,它是Thread -specific ,但不是AppDomain特有的。

You can find a great answer about the difference between AppDomain , Thread and Process here: Difference between AppDomain, Assembly, Process, and a Thread 你可以在这里找到关于AppDomainThreadProcess之间区别的一个很好的答案: AppDomain,Assembly,Process和Thread之间的区别

As for the unloading the AppDomain, I think that you can refactor your code as you can start a worker Thread into your AppDomain with limited access to the system resources, and simply wait for it to be finished, something like it mentioned here : 至于卸载AppDomain,我认为您可以重构代码,因为您可以通过对系统资源的有限访问权限启动工作Thread到您的AppDomain ,并等待它完成,如下所述

using System;
using System.Threading;
using System.Threading.Tasks;

class Program
{
    static void Main()
    {
        var ad = AppDomain.CreateDomain("WhereTheWorkHappens");

        Task<string> t = DoWorkInOtherDomain(ad);
        Console.WriteLine("waiting...");
        Console.WriteLine(t.Result);

        Console.ReadLine();
    }

    static Task<string> DoWorkInOtherDomain(AppDomain ad)
    {
        var ch = new MarshaledResultSetter<string>();

        Worker worker = (Worker)ad.CreateInstanceAndUnwrap(typeof(Worker).Assembly.FullName, typeof(Worker).FullName);
        worker.DoWork(ch);

        return ch.Task;
    }

    class Worker : MarshalByRefObject
    {
        public void DoWork(MarshaledResultSetter<string> callback)
        {
            ThreadPool.QueueUserWorkItem(delegate
            {
                Thread.SpinWait(500000000);
                callback.SetResult(AppDomain.CurrentDomain.FriendlyName);
            });
        }
    }

    class MarshaledResultSetter<T> : MarshalByRefObject
    {
        private TaskCompletionSource<T> m_tcs = new TaskCompletionSource<T>();
        public void SetResult(T result) { m_tcs.SetResult(result); }
        public Task<T> Task { get { return m_tcs.Task; } }
    }
}

As an additional idea for you, you can read about Sandboxing your code with TPL , which, as I think, is better approach as you don't manually manage the system resources and has less chances for being hacked by your non-trusted code. 作为您的另一个想法,您可以阅读有关使用TPL您的代码进行沙盒处理的内容,我认为这是更好的方法,因为您不会手动管理系统资源,并且被不受信任的代码攻击的可能性更小。

Also, you can find a GitHub project with Cross-AppDomain Marshaling friendly TPL wrappers for APM 此外,您还可以找到一个GitHub项目,该项目包含适用于APM的Cross-AppDomain Marshaling友好TPL包装器

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM