也许这可以帮助你。我使用这些类能够监听远程 AppDomains Trace.(Write/WriteLine) 调用。
第一个类是允许我将 TraceListen Write/WriteLine 方法重定向到自定义委托的类。
public delegate void TraceWriterHandler(string message);
internal class SynchronizedTraceListener : TraceListener
{
private TraceWriterHandler messageHandler;
public SynchronizedTraceListener(TraceWriterHandler writeHandler)
{
messageHandler = writeHandler;
}
public override void Write(string message)
{
messageHandler(message);
}
public override void WriteLine(string message)
{
messageHandler(message + System.Environment.NewLine);
}
}
然后是我的远程 AppDomain 跟踪侦听器类的核心。这是棘手的部分。我会尽量不混淆解释。这对我来说很棘手,但它就在这里。
- (本地)CrossDomainTracer 对象在远端 AppDomain 上创建(远端)CrossDomainTracer 对象。
- (本地)CrossDomainTracer 对象调用(远)CrossDomainTracer 对象 .StartListening 并将其自身作为参考发送(本地)。
- (远)CrossDomainTracer 对象开始侦听(远)他的域中的任何 Trace.Write/WriteLine 调用。
- 当进行(远)Trace.Write/WriteLine 调用时,它会从(本地)远程 AppDomain 调用 .RemoteWrite 方法。
- (本地) .RemoteWrite 调用它自己的 AppDomain 范围 Trace.Write 以便(本地)侦听器可以正确显示消息。
笔记:
- AssemblyResolve 确保在尝试引用包含此代码的程序集时出错。
- 此代码必须存在于两个进程中并共享相同的命名空间。我在库中使用它并将程序集引用添加到两个应用程序。
- 还要注意 Serializable 属性和 MarshalByRefObject 继承。这是框架要求在 AppDomain 之间正确编组对象的要求。
[Serializable]
public sealed class CrossDomainTracer : MarshalByRefObject
{
private CrossDomainTracer remoteTracer;
private SynchronizedTraceListener remoteListener;
public CrossDomainTracer()
{
}
public CrossDomainTracer(AppDomain farDomain)
{
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
this.remoteTracer = farDomain.CreateInstanceFrom(Assembly.GetExecutingAssembly().Location, typeof(CrossDomainTracer).FullName).Unwrap() as CrossDomainTracer;
AppDomain.CurrentDomain.AssemblyResolve -= new ResolveEventHandler(CurrentDomain_AssemblyResolve);
if (remoteTracer != null)
{
remoteTracer.StartListening(this);
}
}
public void StartListening(CrossDomainTracer farTracer)
{
this.remoteTracer = farTracer;
this.remoteListener = new SynchronizedTraceListener(new TraceWriterHandler(Write));
Trace.Listeners.Add(this.remoteListener);
}
public void Write(string message)
{
this.remoteTracer.RemoteWrite("AppDomain(" + AppDomain.CurrentDomain.Id.ToString() +") " + message);
}
public void RemoteWrite(string message)
{
Trace.Write(message);
}
Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
try
{
Assembly assembly = System.Reflection.Assembly.Load(args.Name);
if (assembly != null)
{
return assembly;
}
}
catch { }
// Try to load by assembly fullname (path to file)
string[] Parts = args.Name.Split(',');
string File = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\" + Parts[0].Trim() + ".dll";
return System.Reflection.Assembly.LoadFrom(File);
}
}
最后,您可以将所有这些整齐地打包在一个静态类中。
public static class CrossDomainTrace
{
public static void StartListening(AppDomain remoteDomain)
{
new CrossDomainTracer(remoteDomain);
}
}
通过在将注册远 Trace 按摩的应用程序中执行此操作。
CrossDomainTrace.StartListening(theFarAppDomain);
剩下的唯一事情就是将 TraceListner 添加到这一侧的 Trace.Listeners 集合中,以对消息执行任何您想要的操作。
希望能帮助到你。