我正在编写一个 wpf 应用程序来通过 TCP 控制嵌入式设备。写入设备很容易,但我无法接收数据包。
我创建了一个 tcp NetworkStream 并使用 NetworkStream.BeginRead() 来监听 TCP 数据。但是,一旦我编写了一个完整的数据包,我想更新我的 GUI 以反映新信息。似乎不允许我从异步回调线程中执行此操作。
似乎有一种方法可以通过调度程序一次一个请求来执行此操作,但我几乎需要更新我的 GUI 上的每个控件。我不是为每个数据包案例和每个 WPF 控件编写调度程序函数。如何从我的异步线程完全访问 WPF 控件?
编辑: 这是一个代码示例:
NetworkUnion union = (NetworkUnion)ar.AsyncState;
union.BytesRead += tcpStream.EndRead(ar);
if (union.BytesRead < union.TargetSize)
tcpStream.BeginRead(union.ByteArray, union.BytesRead, union.TargetSize - union.BytesRead, new AsyncCallback(ReadCommandCallback), union);
else
{
NetworkUnion payload = new NetworkUnion();
NetworkPacket pkt = (NetworkPacket)union.getArrayAsStruct();
// Respond to the packet
// Read the payload
payload.ByteArray = new byte[pkt.payloadSize];
tcpStream.Read(payload.ByteArray, 0, pkt.payloadSize);
// Determine what the payload is!
switch (pkt.code)
{
case (int)PacketCode.STATE:
payload.ObjectType = typeof(NetworkState);
NetworkState state = (NetworkState)payload.getArrayAsStruct();
Handle.fuelGauge.Value = Convert.ToDouble(state.mainFuel);
break;
当我尝试更新电量计时,我得到一个 InvalidOperationException,调用线程无法访问,因为另一个线程拥有该对象
使用“Handle”变量是因为它来自静态实用程序类
主要问题是,我真的必须更换每一行
Handle.fuelGauge.Value = Convert.ToDouble(state.mainFuel);
和
Handle.fuelGauge.Dispatcher.Invoke(
System.Windows.Threading.DispatcherPriority.Normal,
new Action(
delegate()
{
Handle.fuelGauge.Value = Convert.ToDouble(state.mainFuel);
}
));
? 似乎过于重复了。这样做会更容易:
Handle.mainWindow.Dispather.Lock();
Handle.fuelGauge.Value = Convert.ToDouble(state.mainFuel);
change everything else...
Handle.mainWindow.Dispatcher.Unlock();