1

.NET で VB6 ActiveX EXE をレプリケートしようとして、.NET リモート処理について理解を深めようとしています。

これまでのところ、すべてのクライアントが共有できるサーバー上でインスタンス化されたシングルトンがあります。

シングルトンはクライアントからのリクエストを受け入れてデータを検証し、検証済みのデータをイベントの形式で返します。これはうまく機能します。Singleton への参照を要求するクラスでは、イベントが発生します。つまり、データを送信し、検証済みのデータを受信します。

ただし、これにはインターフェイスが必要です。クライアントは WPF アプリケーション (サーバーも同様) でホストされており、クライアントがデータを受信したら、表示 (テキスト ボックス、リスト ボックスなど) を更新して、クライアントとシングルトンの間の通信を反映する必要があります。

ただし、メインフォームに実装されたイベントを追加して、クライアントがシングルトンからの応答を受信したときに呼び出すとすぐに、メインフォームにシリアル化属性がないことを訴える実行時エラーが発生します....

この簡潔さを保つために、次のようにプロセスを説明します

サーバーは次のコードで実行されます。

            BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider();
            BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();
            //
            IDictionary myDictionary = new Hashtable();
            myDictionary["name"] = String.Format("PracticonChannel_{0}", Port);
            myDictionary["typeFilterLevel"] = TypeFilterLevel.Full;
            myDictionary["port"] = Port.ToString();
            serverProvider.TypeFilterLevel = TypeFilterLevel.Full;

            http = new HttpChannel(myDictionary, clientProvider, serverProvider);

            // Register RemotingShared.SingletonObject as a 
            // Singleton Server-Activated type.
            RemotingConfiguration.RegisterWellKnownServiceType(
                typeof(Practicon.RemotingShared.UploadObjectSingleton), // Server-activated type
                "SingletonService",                     // objectUri
                WellKnownObjectMode.Singleton           // Singleton instancing mode
                );

            RemotingConfiguration.ApplicationName = " Upload Server";
            RemotingConfiguration.RegisterActivatedServiceType(
            typeof(Practicon.RemotingShared.UploadObjectSingleton));

クライアントは、次の方法でサーバーでアクティブ化されたシングルトンを取得します。

HttpChannel http1;
                // Set the formatters of the messages for delivery.
                BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider();
                BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();
                //
                IDictionary myDictionary = new Hashtable();
                myDictionary["name"] = String.Format("PracticonChannel_{0}", Port);
                myDictionary["typeFilterLevel"] = TypeFilterLevel.Full;
                myDictionary["port"] = port.ToString();
                serverProvider.TypeFilterLevel = TypeFilterLevel.Full;
                http1 = new HttpChannel(myDictionary, clientProvider, serverProvider);

                ChannelServices.RegisterChannel(http1, false);


                uploadObj= (UploadObjectSingleton)Activator.GetObject(
                            typeof(UploadObjectSingleton),
                            fullAddress);

//---------- Here's the problem...
                uploadObj.ReplyEvent += new UploadObjectReplyEventHandler(OnUploadReply);

OnUploadReply は、さまざまなコントロールを更新する Form 実装イベントです。これが実行時に割り当てられると、メインフォームにシリアライゼーション属性がないため、シリアライゼーション例外が発生します。

これは私を夢中にさせています。シングルトン内で発生したイベントに応答してユーザーインターフェイスを更新する方法について、誰かが私に見せたり、説明したり、教えたり、説教したり、講義したりできますか?

4

1 に答える 1

1

OK、これに対する答えは、WCF を使用することです。思ったほど怖くはなく、私のソリューションは予想以上にうまく機能します。

私が直面したことをやろうとしている人に強調したいことは次のとおりです。

  1. 明らかに、ホストするサーバー アプリケーションを作成し、サービスをホストするだけです。サーバーアプリを使用してサービスのUIを維持するなど、凝ったことをしてみました - ステータス、何をしていたのか、そして誰に対して/のために。しないでください!ただしないでください。

  2. クライアントとサーバーの間の接続を開いたままにしておいてください。これ以上、チャネルに障害が発生するリスクがあり、何時間もこれを整理しようとして失敗から回復しようとした後、猫を群れにする方法についての指示を書いてみたほうがよいでしょう. あなたの問題を再考してください。開く、使う、閉じる。

  3. とにかく、UI を備えた ActiveX コントロールに代わるものを考え出さなければなりませんでした。サーバー (ホスティング用)、クライアント (サービスのユーザー インターフェイスを提供するため)、サービスと対話する COM インターフェイス (関数と呼ばれる、プロパティを設定するなど) と外部アプリケーションの 3 つのプロジェクトを作成しました。

COM インターフェイスが最初にしなければならなかったことは、サーバーの実行中のインスタンスを見つけようとすることでした (ところで、WPF アプリケーションの単一のインスタンスを実装することは決して簡単なことではありませんが、これはトピックから外れています)。

見つからない場合は、Server アプリを実行し、待機してからチャネルを開きました。このプロセスは、COM インターフェイスがインターフェイスに対して対話/待機する必要があるたびに繰り返されました (明らかに、サーバー アプリは 1 回だけ実行する必要がありました)。球痛ですが、これにより、恐ろしい「チャネルが障害状態にある」症候群が回避されました。以前は、サービスをホストし、チャネルを完全にランダムな時間 (1 分、1 時間、1 日) 開いたままにしておくことができましたが、クライアント/サーバーが何もしていなくても障害が発生していました。私のサービスは北米 (英国から) の生産ラインを制御しており、インターフェースがダウンした場合は、再び実行されるまで何も行われないため、私の優先事項は安定性でした。だからロックとかハードとかいう言葉が頭から離れない

だから、繰り返す、開く、使う、閉じる。

お役に立てれば。

んん

ところで、私はBlamの提案に賛成しました。

于 2013-12-19T21:29:17.623 に答える