也許這可以幫助你。 我使用這些類可以偵聽遠程AppDomain 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確保錯誤,同時嘗試引用包含此代碼的程序集。
- 此代碼必須存在於兩個進程中並共享相同的名稱空間。我在庫中使用它,並將程序集引用添加到這兩個應用程序。
- 另請注意,可序列化屬性和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);
}
}
Finnaly可以整齊地打包這一切在一個靜態類。
public static class CrossDomainTrace
{
public static void StartListening(AppDomain remoteDomain)
{
new CrossDomainTracer(remoteDomain);
}
}
通過在應用程序中這樣做,將註冊遠程跟蹤按摩。
CrossDomainTrace.StartListening(theFarAppDomain);
剩下的唯一的事情就是一個TraceListner添加到收藏Trace.Listeners在這方面做你想要的信息什麼都。
希望它有幫助。
它有幫助。謝謝。我最終將TextWriter的引用從默認appDomain發送到遠程,並在RemoteWrite方法中使用WriteLine。 – wazelin 2013-03-22 08:19:55