3

TCP 経由でサーバーに接続し、定期的なデータを受信する C# コンソール アプリケーションを作成しています。ここで見つけたコードを使用しています。これは、使いやすい非同期クライアントです。これを使用して、コードが起動し、接続を確立してからイベントを待機します。

static void Main(string[] args)
        {
            agents = new ObservableCollection<AgentState>();
            EventDrivenTCPClient client = new EventDrivenTCPClient(IPAddress.Parse("192.168.0.1"), 5000);
            client.DataReceived += new EventDrivenTCPClient.delDataReceived(client_DataReceived);

               client.Connect();

                do
                {
                    while (!Console.KeyAvailable)
                    {
                        Thread.Sleep(50);
                    }

                } while (Console.ReadKey(true).Key != ConsoleKey.Q);

client.Disconnect();

       }

これによりアプリが起動し、ポート 5000 で 192.168.0.1 に接続してから、応答のリッスンを開始します。それらを受信したら、「clients」という名前の ObservableCollection (オブジェクト「ClientState」で構成される) を結果で更新します。

 static void client_DataReceived(EventDrivenTCPClient sender, object data)
    {
               string received = data as string;

        string parameters=received.Split(',');

        ClientState thisclient = clients.FirstOrDefault(a => a.clientName == parameters[0]);

        var index = clients.IndexOf(thisclient);
        if (index < 0)
        {

            ClientState newclient = new ClientState();
            newclient.clientName = clientname;
            newclient.currentState = state;
            newclient.currentCampaign = campaign;
            clients.Add(newclient);
        }
        else
        {
            clients[index].currentState = state;
            clients[index].currentCampaign = campaign;
        }

    }

驚いたことに、これはすべて正常に動作します。コードは順調に進み、統計を収集し、ObservableCollection に追加および更新します。ただし、問題は PropertyChanged にフックしようとするときです...最初に、追加します

   clients.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(agents_CollectionChanged);

Main() に、次に追加します。

    static void clients_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {

                 foreach (INotifyPropertyChanged item in e.NewItems)
                     item.PropertyChanged += new PropertyChangedEventHandler(newagent_PropertyChanged); 
    }

ObservableCollection で何かが変更されたときに newagent_PropertyChanged メソッド (現時点ではコンソールに吐き出すだけ) を呼び出すようにしたいのですが、何らかの理由で、PropertyChanged イベントが発生するとすぐに、" TCP コードの cbDataRecievedCallbackComplete」メソッド:

タイプ 'ClientState' のオブジェクトをタイプ 'System.ComponentModel.INotifyPropertyChanged' にキャストできません。

...どういうわけか、PropertyChangedを発生させようとする行為は、「cbDataRecievedCallbackComplete」コードを起動させています。イベントが「交差点」であるかのようです。エラーを「キャッチ」すると、コードは停止し、それ以上受信データを処理しません。

これが私が導入した問題なのか、それともソースコードの問題なのかを知るには十分な経験がありません。私はそれが前者であることにお金をかけます: 誰が問題がどこにあるのか見ることができますか?

更新:以下の回答に応じて、クラス定義を次のように変更しました。

  public class ClientState : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            var handler = PropertyChanged;
            if (handler != null)
                handler(this, new PropertyChangedEventArgs(propertyName));
        }

        public string agentName { get; set; }
        public string currentCampaign { get; set; }

        public string _currentState;
        public string currentState
        {
            get { return _currentState; }
            set
            {
                if (value != _currentState)
                {
                    _currentState = value;
                    OnPropertyChanged("CurrentState");

                }
            }
        }
    }

...だから、「currentState」への変更がイベントをトリガーすることを期待しています。ただし、同じ場所でエラーが発生しますが、エラーは次のとおりです。

オブジェクト参照がオブジェクト インスタンスに設定されていません。

r.DataReceived.EndInvoke(result)cbDataRecievedCallbackCompleteの行にあります。

4

2 に答える 2

2

例外は次の行によって発生します。

foreach (INotifyPropertyChanged item in e.NewItems)

e.NewItems各オブジェクトをに暗黙的にキャストしていますINotifyPropertyChangede.NewItemsのインスタンスが含まれているため、実装していないClientStateと推測しています。ClientStateINotifyPropertyChanged

于 2012-06-06T15:36:01.387 に答える
2

ClientState のクラス定義がこのように見えない場合

public class ClientState : INotifyPropertyChanged

その場合、それをタイプ INotifyPropertyChanged にキャストすることはできません。e.NewItems コレクションはオブジェクト型であるため、コンパイル時の例外は発生しません。そのため、何かにキャストしようとすることができます。

于 2012-06-06T15:40:37.910 に答える