当我们使用Win7或其他操作系统的RDC关闭并重新连接到此计算机时,Win8.1将向WPF应用程序触发卸载和加载事件 [英] Win8.1 will fire unload and load event to the WPF application when we close and reconnect to this machine using RDC from win7 or other OS

查看:233
本文介绍了当我们使用Win7或其他操作系统的RDC关闭并重新连接到此计算机时,Win8.1将向WPF应用程序触发卸载和加载事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这仅在Win8.1中是一个奇怪的问题.

This is a strange issue only in Win8.1.

众所周知,如果计算机中存在正在运行的应用程序,则在通过远程桌面连接连接/断开连接/重新连接到该计算机时,应用程序不应有任何其他行为.但是,我们发现,当我们关闭并使用RDC重新连接到计算机时,Win8.1将向WPF应用程序触发卸载和加载事件.这是一种不良行为,可能会导致错误.

As we all know, if there is a running application in a machine, there should not be any other behavior against the application when we connect/disconnect/reconnect to this machine by Remote Desktop Connection. However, we found that Win8.1 will fire unload and load events to the WPF application when we close and reconnect to the machine using RDC. And this is an unwanted behavior which may cause error.

以下是稳定的复制步骤:

Here are the stable reproduce steps:

  1. 编写一个WPF应用程序,其中包含一个按钮并处理此按钮的卸载和加载事件.
  2. 例如,使用RDC从Win7连接到Win8.1.
  3. 在远程桌面上,运行此WPF应用.(加载事件将记录在a.txt中.)
  4. 通过单击"x"关闭RDC.
  5. 再次连接到此Win8.1.
  6. 您将看到已触发了卸载和加载事件.

如果WPF应用程序在Win7或Win Server 2008中运行,则不会触发这些事件.

If the WPF app runs in Win7 or Win server 2008, those events will not be fired.

所以,我认为这是Win8.1中的有害行为.那是Win8.1 RDP中的错误吗?还是这是一项新功能?

So, I think it is a unwanted behavior in Win8.1. Is that a bug in Win8.1 RDP? Or is that a new feature?

推荐答案

之所以会发生这种情况,是因为重新连接RDP会通知WPF代码会话和屏幕已更改. WPF需要重建其DirectX资源,并可能处理更新的屏幕尺寸(即使分辨率可能相同). b/c这很有意义,RDP客户端可以从RDP体验"选项卡中指定不同的功能,例如图形级别和其他属性. WPF不能确定参数是否与上次连接完全相同,并且会触发新的渲染和布局周期(这很有意义,因为颜色和屏幕分辨率可能已更改).这将导致控件被重新加载并触发新的Loaded事件.

This occurs because reconnecting RDP notifies the WPF code that session and screen has changed. WPF needs to rebuild its DirectX resources and probably handle an updated screen size (even though resolution may be the same). This makes sense b/c the RDP client can specify different capabilities such as the graphics level and other properties from the RDP "Experience" tab. WPF does not determine that the parameters are all the same as the last time a connection occurred and it triggers a new render and layout cycle (makes sense since colors and screen resolution may have changed). This leads to controls being re-loaded and a new Loaded event firing.

通过检查.NET源代码中的HwndTarget.cs,您可以看到很多细节.在此文件中搜索会话",您会看到很多会话断开/重新连接的处理方法.

You can see much of the gory details of this by examining HwndTarget.cs in the .NET source. Search this file for "session" and you'll see a LOT of handling for session disconnect/reconnect.

http://referencesource. microsoft.com/#PresentationCore/Core/CSharp/System/Windows/Interop/HwndTarget.cs,f20f989ef219e391

如果您想找到一种避免在已加载/已卸载代码中进行额外工作的方法,则可能必须将其移至确保仅通过标志或空检查调用一次的函数.

If you want to find a way to avoid doing extra work in your Loaded/Unloaded code you may have to move it to a function which you make sure you only call once via a flag or null check.

您可以通过在Loaded事件处理程序上添加断点并转到工具">选项",调试并取消选中启用我的代码",然后选中启用.NET Framework源代码步进"并选中启用"来见证发生的情况源服务器"支持.当您连接RDP时,bkpt将触发,并且调用堆栈将在其他级别的调用之间显示一个调整大小事件.这可能是由于WPF还获得了WM_DISPLAYCHANGE并重新布局了所有内容,以防此连接具有更多或更少的分辨率.

You can witness what's happening by adding a breakpoint on your Loaded event handler and going to Tools > Options, Debugging and un-check "Enable Just My Code", and check "Enable .NET framework source stepping" and check "Enable Source Server" support. When you connect RDP, the bkpt will trigger and the call stack will show a resize event among other levels of calls. This was probably due to WPF getting a WM_DISPLAYCHANGE as well and having everything re-layout in case there's more or less resolution with this connection.

这篇关于当我们使用Win7或其他操作系统的RDC关闭并重新连接到此计算机时,Win8.1将向WPF应用程序触发卸载和加载事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆