2011-10-19 64 views
2

私は(間違いなく汚い)ソークテストランナーを作成する必要がある状況があります。そのアイデアは、TasksやThreadPoolのようなものを使って大量のテストを一度に実行することです。アプリケーションのドメイン切り替え

問題は、静的なものを使用する(よく開発されていない)ヘルパークラスをたくさん使用することです。これは、すべてが解体されて使用された後に再起動されたときに問題になることはありませんでした。つまり、同じアプリドメイン内で複数のスレッドを開始すると、同じ統計情報が使用され、状況が乱雑になります。

注:それは私がやっているテストに基づいた前提ですが、私はそれが問題であることを100%確信していません。

私は新しいアプリケーションドメイン(AppDomain.Create)を作成しようとしたし、それを使用してクラスのインスタンスを作成した(domain.CreateInstanceFromAndUnwrap)、そしてそれは、インスタンスを作成し、私はそれにメソッドを呼び出すことができました。問題は、新しいAppDomainで実行されていないように見えるということです。ここで

は、私がこれまで持っているコードです:今

static void CallBack(BasePerfTest bpf) 
    { 
     Console.WriteLine("CurrentAppDomain (WithinCallback): {0}", Thread.GetDomain().Id); 
     AppDomain newdomain = AppDomain.CreateDomain(Guid.NewGuid().ToString()); 
     //newdomain.ExecuteAssembly(".\\PerformanceTestRunner.exe", new string[] { bpf.ToString() }); 
     ProcessRunner pr = (ProcessRunner)newdomain.CreateInstanceFromAndUnwrap(Assembly.GetExecutingAssembly().Location, "PerformanceTesting.ProcessRunner"); 
     pr.RunProcess(bpf); 
    } 

} 
[Serializable] 
public class ProcessRunner 
{ 
    public void RunProcess(BasePerfTest bpf) 
    { 
     Console.WriteLine("CurrentAppDomain (WithinPR): {0}", Thread.GetDomain().Id); 
    } 

} 

、私はRunProcess()メソッドは、ドメイン内で実行されますが、DOMAINIDはまだ同じであるため、それが問題に当たっていますされていることを期待します統計は衝突している。

ここでは、別のコンソールアプリケーションを作成しました。コメントアウトされた行には、実行に使用したコードが表示されます。このDIDは新しいドメインで実行されますが、その理由はなぜですか。

就寝時の読書の方向性が指摘されているのはうれしいことですが、私は過去の日のことを考えています。正しい言葉を使わないといけないと思います。

ご迷惑をおかけして申し訳ありません。

おかげで、 マーティン

答えて

4

AppDomainの境界線の上にオブジェクトを公開するには、2つの方法があります。

  • Serializableは - あなたがコピーを取得して、オブジェクトをシリアル化します。
  • MarshalByRefObject - リモーティングを使用してオブジェクトにプロキシを作成します。

ProcessRunnerクラスの場合は後者が必要です。

MarshalByRefObjectからクラスを継承してください:

public class ProcessRunner : MarshalByRefbject 
{ 
    public void RunProcess(BasePerfTest bpf) 
    { 
     Console.WriteLine("CurrentAppDomain (WithinPR): {0}", Thread.GetDomain().Id); 
    } 
} 

2番目のAppDomainであなたのクラスをインスタンス化するときは、プロキシを取得。 MSDNのMarshalByRefObjectのドキュメントの例も役立ちます。これは、あなたがしようとしていることをほぼ正確に示しています。

+0

あなたは最高です。 – Martin

2

ProcessRunnerクラスは、System.MarshalByRefObjectから継承する必要があります。起こっているのは、オブジェクトがセカンダリappdomainで実際に作成されていることですが、ローカルの 'pr'変数に割り当てると、それをプライマリappdomainに値を戻して、実際にはProcessRunnerの2番目のインスタンスを作成しますプライマリappdomain。MarshalByRefObjectから継承した場合、prはセカンダリappdomainにあるオブジェクトへの呼び出しを転送するトランスペアレントなプロキシオブジェクトを取得します。

+0

申し訳ありませんが、あなたの答えは同じですが、マークが最初に得ました。でも助けてくれてありがとう – Martin

関連する問題