Thin synchronization classes relate to AppDomain or process?

All articles on the Internet say that using Thread.Abort is evil (since synchronization primitives are related to the operating system and the process is not yet completed, and the primitives may remain blocked after the thread is interrupted). Developers advise terminating entire processes instead, since the operating system will release synchronization primitives when the process stops.

  • Will AppDomain help with unloading if you use Slim synchronization primitives? (With .net 4.0, several new classes related to stream processing have been ManualResetEventSlim : ManualResetEventSlim , SemaphoreSlim , ReaderWriterLockSlim ).

    The documentation says that these primitives cannot be used in different processes, since the implementation code of the primitives is completely managed. But I don’t understand if these primitives will work across the AppDomain border. (see Unable to set synchronization context when using application domains )

  • If so, how do they do it? If not, why does the documentation omit this restriction?

UPD: All my code trusts me, including the code inside the domain that I upload. I do not want to leave the thread working when the time comes to stop it. I want to stop (interrupt) the stream instead of “set the flag” and “make a beautiful architecture”. If you need to create an additional stream first (I think this is necessary when starting background processing in a separate domain to create another stream), I will. I don’t want to use the “setting flag” approach, because it requires me to use the background algorithm of the tool with the flag check, I don’t have to, is this the runtime or the compiler should automate this equipment for me. Now there is no such toolkit, therefore I try to apply this approach when unloading the domain.

Adding checks between each instruction (or in deep nested loops) will significantly slow down the code. Adding checks to random locations will not guarantee a quick end. If problems with writing intermittent code can be resolved, why not try to interrupt the threads and unload the domain?

+5
source share
1 answer

You misunderstand the definitions of AppDomain , Process and Thread - AppDomains always lives in one , but one process can be a master for different AppDomains *:

The ability to run multiple applications within the same process significantly increases the scalability of the server.

  • this is similar to Thread , just for mention.

So, the answer to your question is Yes , subtle synchronization primitives will work with various AppDomains , since there are no end-to-end calls in this architecture, but only a logical difference for different processes.

Regarding the related issue, there are no problems with synchronization primitives there, only with the SynchronizationContext , which Thread specific , but not AppDomain specific.

You can find a great answer about the difference between AppDomain , Thread and Process here: The difference between AppDomain, Assembly, Process and Thread

As for unloading the AppDomain, I think you can reorganize your code, since you can run the working Thread in your AppDomain with limited access to system resources and just wait until it is completed, for example, it is mentioned here :

 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 the sandbox with the TPL code , which, it seems to me, is better since you do not manually manage system resources and are less likely to be hacked by your untrusted code.

Alternatively, you can find the GitHub project with Cross-AppDomain Marshaling friendly TPL wrappers for APM

+2
source

All Articles