2

私は自分のWCF(自己ホスト型)コードを片付けていて、ServiceHostオブジェクトが最初にセットアップされた後、スコープ外になっていることに気付きましたが、それでも接続できました。

public void StartMyService()
{
    var host = new ServiceHost(typeof(MyService), new Uri("http://localhost:8000/MyService"));
    host.Open();
}

これをもう一度呼び出して再インスタンス化してもう一度開くと、エンドポイントに接続されているものがすでにあるというエラーが表示されます。アプリケーションがシャットダウンしたときにのみリリースされます。

Open()の呼び出しは、現在は管理されていない方法で開いたままにするために、より低いレベルで何かを実行すると想定することしかできません。しかし、私がここで物事を完全に誤解していない限り、これに関する情報を見つけることはできません。

そしてそれについて考えると、これは実際には接続がまだ開いているようには見えませんが、アプリを強制終了せずに接続に戻る(閉じるなど)方法はありません。それとも、これは問題ではないかもしれませんが、何も害がなければ、常に開いたままにしておくことができますか?

更新:それで、スコープ外になった後も開いたままになる理由についての私の最初の質問を説明しているので、Eiverの答えを受け入れました。しかし、私は今、これについていくつかのことを疑問に思っています(またはおそらく私のスレッドの経験不足)。第一に、それが開いている限り、私はこのcosについて悩んでいますか?それがすべて正しいことです。また、スレッドをスコープ内に保持してスレッドにアクセスする方法がある場合は、それも役立ちます。たぶん、このように設定すると(そして決してcloseを呼び出さないで)、呼び出しコードが単純になり(つまり、参照を保持する必要がなくなります)、静的メソッドでラップしてさらに単純な呼び出しを行うこともできます。すべてが少しかわすように聞こえます....うーん!

更新2:それで、この方法でそれを行うのは良くないことを知っていました。それは、ホストとそれが開始されたスレッドを制御できなくなったことを意味するからです。そのため、すべてをシングルトンとしてラップし、任意の時点(エラー、イベント、同じエンドポイントでのクローズ/再開など)でホストにアクセスでき、呼び出しを非常に単純にする(単純な静的メソッドのように)という利点があります。電話)。

4

3 に答える 3

1

範囲外になるすべてが終了するわけではありません。クラスが別のスレッドを生成する場合(そしてWCFが生成すると確信しています)、スレッドを作成したクラスへの参照がガベージコレクションされた場合でも、スレッドは存続する可能性があります。

host.Close()を呼び出す必要がある場合があります

于 2012-07-13T17:49:11.880 に答える
1

私の推測では、StartMyService()メソッドを持つクラスはまだ生きています。このようにコーディングすると、(私が思うに)それが行うはずのことを実行します。コメントアウトされたコードは、サービスを開始してスコープ外に出すためのよりクリーンな方法だと思うので、残しておきます。

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("**** Console Based WCF Host *****");

            //using (ServiceHost serviceHost = new ServiceHost(typeof(MagicEightBallService)))
            //{
            //    serviceHost.Open();
            //    Console.WriteLine("The service is running");
            //    Console.ReadLine();
            //}
            using (MySvc ms = new MySvc())
            {
                ms.StartMyService();
            }
            Console.ReadLine();
        }

        public class MySvc: IDisposable
        {
            ServiceHost serviceHost;
            public void StartMyService()
            {
                serviceHost = new ServiceHost(typeof(MagicEightBallService));
                serviceHost.Open();
            }
            public void Dispose() 
            {
                // the class needs to clean up after itself
                serviceHost.Close();
            }
            public MySvc() { }
        }
    }
于 2012-07-13T19:00:03.610 に答える
0

アクセスしようとする前に収集されていない可能性があります。

于 2012-07-13T16:34:50.637 に答える