my assumption would be that the context for thread is known at current
point in time, and the domain needs to be searched based on current
context.
Indeed, in the current implementation of the .NET Framework the Context
object keeps a reference to its parent domain. The Framework designers might have exposed the context's domain as Thread.Context.Domain
. It probably would be a rhetorical question why they didn't do so; I can't tell that by looking into the reference source code.
What matters is that at any given moment of time, the thread is executing code inside a particular domain. This would be either the process's default domain, or the domain entered via AppDomain.DoCallBack
, AppDomain.ExecuteAssembly
or a marshalled MarshalByRefObject
-object. That'd would be the domain Thread.GetDomain()
returns.
This domain has at least one context (the default one), but it may also have other contexts, created for ContextBoundObject
-objects. It's possible to enter any of those contexts explicitly on the same domain via Context.DoCallBack
or implicitly from any domain by calling a marshalled ContextBoundObject
-object. That'd be the context Thread.Context
returns.
There is no parent-child relationship between thread and domain or thread and context. However, there is strict parent-child, one-to-many relationship between domain and its contexts. So, the domain doesn't need to be searched based on current context.
If you like to play with it a bit more, here is the app I used:
using System;
using System.Runtime.Remoting.Contexts;
using System.Threading;
namespace ConsoleApplication
{
public class Program
{
[Synchronization]
public class CtxObject : ContextBoundObject
{
public void Report(string step)
{
Program.Report(step);
}
}
public static void Main(string[] args)
{
Program.Report("app start");
System.AppDomain domain = System.AppDomain.CreateDomain("New domain");
var ctxOb = new CtxObject();
ctxOb.Report("ctxOb object");
domain.SetData("ctxOb", ctxOb);
domain.DoCallBack(() =>
{
Program.Report("inside another domain");
var ctxOb2 = (CtxObject)System.AppDomain.CurrentDomain.GetData("ctxOb");
ctxOb2.Report("ctxOb called from another domain");
});
Console.ReadLine();
}
static void Report(string step)
{
var threadDomain = Thread.GetDomain().FriendlyName;
Console.WriteLine(
new
{
// Thread.CurrentContext.ContextID is only unique for the scope of domain
step,
ctx = Thread.CurrentContext.GetHashCode(),
threadId = Thread.CurrentThread.ManagedThreadId,
domain = Thread.GetDomain().FriendlyName,
});
}
}
}
Thread
andContext
are independent entities. AContext
is something associated withContextBoundObject
-objects, not threads. Multiple contexts can flow through the same thread (withContext.DoCallBack
), and multiple threads can share the same context (Thread.CurrentContext
). You cannot though "move" a thread to another domain. Related: https://mcmap.net/q/213281/-is-await-supposed-to-restore-thread-currentcontext/1768303. – MariquillaAppDomain.DoCallBack
. Although I stand corrected: there is no parent-child relationship between domain and thread, unlike I thought there would be. – Mariquilla