【问题标题】:Using event-driven TCP client and NotifyPropertyChanged together causes exception一起使用事件驱动的 TCP 客户端和 NotifyPropertyChanged 会导致异常
【发布时间】:2012-06-06 15:31:14
【问题描述】:

我正在编写一个 C# 控制台应用程序,它通过 TCP 连接到服务器并接收周期性数据。我正在使用我找到的一些代码here,这是一个非常易于使用的异步客户端。使用它,我的代码启动,建立连接,然后等待事件:

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”(由对象“ClientState”组成)的 ObservableCollection:

 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”的任何更改都会触发一个事件。但是,我在同一个地方得到一个错误,除了现在错误是:

对象引用未设置为对象的实例。

在 cbDataRecievedCallbackComplete 的 r.DataReceived.EndInvoke(result) 行中。

【问题讨论】:

  • 所以...这里最明显的问题是您的 ClientState 类是否实现了该接口?
  • 希望如此 :) 我在上面添加了类定义。
  • 已修复!我删除了“CollectionChanged”处理程序和事件,现在我很高兴在 CurrentState 更改时收到通知。我不确定到底是什么修复了它,但感谢大家为我指明正确的方向!

标签: c# .net tcp inotifypropertychanged


【解决方案1】:

如果您对 ClientState 的类定义看起来不像这样

public class ClientState : INotifyPropertyChanged

那么您不能将其转换为 INotifyPropertyChanged 类型。您没有收到编译时异常,因为 e.NewItems 集合是对象类型,因此您可以尝试将其转换为任何内容。

【讨论】:

  • 已修复,见上文!感谢您的帮助。
【解决方案2】:

异常将由这一行引起:

foreach (INotifyPropertyChanged item in e.NewItems)

您将e.NewItems 中的每个对象隐式转换为INotifyPropertyChanged。由于e.NewItems 包含ClientState 的实例,我猜ClientState 没有实现INotifyPropertyChanged

【讨论】:

  • 它没有,所以我有 - 见上文。不幸的是,它仍然抛出该错误:(
猜你喜欢
  • 2012-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-21
相关资源
最近更新 更多