`
9alexking
  • 浏览: 8836 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
社区版块
存档分类
最新评论

从Win8回顾微软平台的各种技术

阅读更多

我安装好Win8 CTP后做的第一件事情就是用调试器研究Win8各个组件的协作关系从我半天的研究结果看来, Win8真是一个让我爱不释手的产品. Win8里面涉及到的很多技术正好也是我的兴趣所在这篇文章简单回顾一下这些技术的变迁优缺点和对Win8的影响.

注意下面提到的对Win8的分析是基于公开的Win8 CTP来做的相信Win8面世的时候这些技术和细节都会发生重大改变所以这篇文章不具备实践上的指导价值.

COM -Common Object Model 通用组件模型

COM是上个世纪中期设计出来的伟大产品. COM旨在解决软件复用的问题COM以前大家都是用代码级别的复用常见的就是C/C++的库无论是原代码库还是lib都是需要编译后才能重用的. COM使得技术人员可以在二进制上进行复用Win95, OLE32Office95系列开始, COM就是微软平台上的一个技术基石无论是DirectX API, 还是最常见的剪贴板以及后来.NET Frameworkhost接口都离不开COM. 但任何伟大的产品都有局限的一面. COM在局限性在下面一些地方

STA/MTA/NTA等等线程模型过于复杂

线程模型特别是STA, 设计的目的是方便使用者COM的线程模型严重依赖于太多系统组件比如Win32 Message, RPCWindows系统服务使得程序员需要熟悉和了解太多系统知识才可以正确地使用线程模型否则用STA导致死锁简直就是家常便饭.

开发工具没有提供足够支持

COMVisual Studio 6.0的关系就如同现在CLR2/VS2005, CLR3.5/VS2008CLR4/VS2010的关系一样铁使用COM开发当时的选择要么是VB6, 要么用ATL. 这两者都有天生的局限. VB6适合企业开发特别是当时流行的MIS系统数据库系统这样的CS应用但是VB6不够灵活而且VB6里面由于缺少多线程支持无法用MTA的模型. ATL功能强大足够灵活但是使用起来特别复杂每次实现一个接口都要做一大堆C++的仪式性工作比如实现多重继承定义新的模板使用大量的C神经再粗大的程序员都经不起这样用C++.

无止境地扩充到DCOM, COM+, DTC, MSMQ以及后来的.NET Remoting/WCF, 使得最后的复杂度无法控制

为了更好地适应企业级别的开发, COM被进一步延伸和演化成了DCOMCOM+. 所谓"企业级别", 其实是指对安全性和可伸缩性的更高要求经典的COM是一个进程内模型无法让不同的代码运行在不同的帐号下的因为同一个进程只能启在唯一的帐号下虽然通过impersonate等方法可以适当地解决问题但是为了让安全模型更为全面正确的做法是让不同的接口实现能够跨越进程甚至跨越机器等安全边界运行要能够赋予不同的接口不同的安全级别能够和域帐号集成支持不同等级的加密等等.远程通用组件模型也就是DCOM就这样诞生了读者可以尝试运行以下dcomcnfg.exe这个工具展开一些节点看看属性页就能体会到DCOM的功能是多么让人眼花缭乱了对于可伸缩性微软更上一层楼DCOM的基础上加入了对象池和新的同步模型做成了COM+. 风靡十年的ASP, 就是运行在COM+框架下的最好例子更让人叹为观止的是微软把DTCMSMQ的设计也和COM+模型绑定起来陌生的读者可能不了解DTC是个多么nb的东西简单说DTC是可以让程序员一行代码都不用写就让SQL ServerOracle的数据库操作运行在同一个事务边界里面可以想象MSSQL Server刚进入市场的时候微软推出这样的功能对于抢占Oracle的市场份额有多么重要. DTCCOM+当时成为了很多大公司的标准配置以至于后来设计.NET RemotingWCF的时候都还是要考虑对DTC的支持这些强大而且复杂的功能让本来就复杂的COM更加恐怖这样的复杂度虽然也体现了当时的市场需求但由于缺乏配套的开发工具新的开发语言和更优美的抽象使得这条路最后越走越窄.

.NET Framework/CLR

在我眼中, CLR的各方面简直是无可挑剔的但可能正是因为CLR太好了让微软从2003年开始unmamanged world的投资就不大了.

为了争取企业客户全力推广CLR是最正确的做法毕竟绝大多数的程序员一辈子都是和数据库UI代码打交道你总不能让他们一辈子都用C去管理内容创建窗口句柄吧. CLR的性能也很有竞争力与之对应的编程语言和开发工具也非常给力每个新版本都带来长足进步但是这些再好也无法掩饰一个悖论要用用C#写出性能可以和C++一个数量级的程序不是不可能而是花费的代价往往比直接用C++写更大这里面有很多原因比如系统最底层的API还是unmanaged通过CLRinterop的性能损失无法忽略比如用C#的话程序员的控制力很弱从工具和语言层面上很难对性能精雕细作一不注意就box/unbox比如JIT编译器为了实现自己的安全模型和异常处理每次访问成员函数的都是都要生成代码确认this指针是否为空这个世界上还是有很多程序是需要对性能做严格控制的CLR高速发展的几年中对应的系统平台, Win32 API, C++开发工具只有完善性的改善并没有重大突破这个问题对Windows平台本身影响不大但如果寄希望于在移动设备上大家都指着C#来开发就有点天方夜谭了这样的失衡使得微软在移动设备和消费者产品这两个严重需要unmanaged和系统投入的领域缓慢发展了很长时间.

WPF

在我看来, WPF是一个设计得很美的产品. WPF解决了传统Win32 UI程序的四大局限. 1) Win32的绘图是由各自Window元素独立控制基于GDI. WPF引入了rendering thread来提高性能优化算法借用GPU加速. 2) Win32依赖于GDI Object, 在开发复杂窗口程序的时候很容易就遭遇资源泄露和资源不足比如早期的淘宝旺旺开到几十个窗口的时候程序就会出问题所以淘宝针对这个问题使用了统一控制台合并多个窗口到标签页的方法来解决WPF只有最外面的窗口使用了Win32 WindowGDI, 内部的元素都是抽象成了WPF自己的元素不额外占用Win32 GDI资源的. 3) Win32窗体程序严重依赖Windows Message模型这要求程序员对系统知识有深入的了解而且Win32 API并不是非常利于使用比如要进行UI threadWorker thread之间的通信往往需要和SendMessage这样的API打交道WPF引入了Dispatcher类和BeginInvoke方法把这些复杂问题抽象了加上CLR提供了更方便高效的开发环境使用WPF是很愉快的工作. 4) Win32缺乏数据设计和代码三者之间的模式抽象这三者在WPF中对应了数据绑定, XAML文件以及后台代码WPF中可以更直观地使用各种模式比如MVCMVVM. 这些都体现了WPF设计上的优美.

再优美的东西都还是有局限性的. WPF的问题在于过多的模式和对CLR过度的依赖了解WPF框架的人都知道就一个简单的dependent property, 就把设计模式这本书里面的模式用掉一大半了分析WPF框架代码的话简直就是看一本设计模式的百科全书我曾经统计过关于mouse click这样一个event回调, WPF里面有7种不同的实现方法分别各有好处旨在解决不同问题在这样高度灵活的背后牺牲的是程序性能无论是五花八门的模式还是最常用的数据绑定背后的主力都是CLRreflection. 过度依赖于reflection导致WPF程序规模一大性能上就出问题就算再怎么优化也总找不到原生Win32程序那般流利的感脚使用reflection也体现了对CLR的依赖所以前面CLR的局限性也适用于WPF.

微软产品的互操作性

微软的产品线虽又长又多但是各个产品之间一定是能够互操作的比如C#可以和C++互相调用任何语言开发的程序都可以嵌入Browser Control来借用IE的功能. Office暴露了VBA接口通过VBScript都能够自动化Office程序各种管理工具无论是Explorer还是MMC, 都暴露了编程接口可以让程序员添加自己的功能我见过客户用ASP.NET在后台用VBScript生成Excel表格然后把表格嵌入在 IE浏览器中再使用JavaScript来帮助客户编辑最后提交回MSSQL数据库做完成报销功能的完善的互操作性充分保护了用户的投资使得客户对微软平台用一次就上瘾几乎没有不可能完成的任务仔细分析其实这些互操作有一个共性都是把暴露COM接口作为内部实现原理这个做法导致了三个局限性首先是牵涉到了前面提到的COM的复杂度其次是潜在的性能损耗最后是在具体开发的时候都需要一些仪式性的工作来引入或者定义COM接口使得开发过程不够自然流畅CLRCOM互操作的调用栈里面, CLRRCW, CCW, 安全处理列集拷贝等等耗费的时间带来的性能开销简直是可以到了肉眼可察觉的地步(听硬盘的声音和看任务管理器里面CPU的波动).

Win8

在讨论完这些技术背后的故事后再看看为啥我就对Win8爱不释手了.

Win8引入了Windows Runtime, 简称WinRT. WinRT是一个操作系统模块运行在用户态介于Win32的上层和应用程序的下层目的在于提供更高效友好的开发接口供Win8的程序员使用. WinRT在二进制模型上基本就是照搬了经典的COM. WinRTCLR互不依赖, WinRT可以被CLR使用. WinRT通过C/C++实现效率高是一个方面更重要的时Win8引入了projection的概念就是可以把WinRTAPI用最直接最高效的方法提供给上层的编程语言调用这个语言可以是C#, C或者JavaScript.

对于第一次接触Projection的朋友可以把Projection认为是一种新的Windows API模型传统的操作系统API, 要么是暴露DLL的方法要么是通过COM接口无论是哪一种CLR中调用的时候都有不小的开销使用这些传统API的效率比调用一个C#自己的方法效率差了多个数量级根本的原因在于CLR的安全模型内存模型和传统的unmanaged模型不兼容所以跨越边界的调用需要额外的代码来处理Projection提供的模型是在提供新功能的同时还针不同编程模型和语言提供了最利于它们调用的方法这样就主动避免了不同模型之间为了互相兼容导致的开销也使得程序员写代码的时候非常自然流畅调用的时候根本感觉不到和调用本地函数的区别当然能够实现这一点也是得益于CLR, C#语言和VS开发工具这十年的长足发展举个例子, C# 5.0中引入了await关键字, WinRT中引入了async operation. Projection技术把C#中的await语句转换为WinRT async operation的调用而且这个调用直接从managed code直接跳到unmanaged code, 中间没有任何冗余也不需要CLR Engine的介入进一步的信息可以参考Build大会关于WinRT的多个演讲后面的callstack也提供了直观的例子.

前面提到了COM的局限性在于一个轻量的二进制模型被硬生生的扩展成一个无所不能的框架. WinRT取其精华去其糟粕借用了COM的轻便舍弃了复杂性在扩展性上依托于上层的编程语言和工具. WinRT通过projection的技术解决了传统互操作性效率不高使用不方便的问题以前的路线是希望所有的产品和技术最后都统一到CLR上来现在修正为底层模型通过WinRTC来实现然后把这一层高效的组件无缝提供给上层的开发技术比如CLR来使用这个转变重新重视unmanaged层面的二进制模型归纳为, unmanaged模型的优势在于执行效率高可以通吃所有场景缺点在于开发和使用成本也高. CLR的优势在于开发成本低缺点在于无法通吃各种需求现在微软自己用unmanaged来做WinRT, 然后把WinRT提供给上层语言这两者就可以取长补短了.

有了WinRT, 有了unmanaged的回归再加上微软开发工具和C#语言的长足发展前面介绍的各种技术在Win8里面就相得益彰了. Metro是如何修复WPF的缺陷就显而易见了: Win8metro程序继续使用WPF中引入的rendering模型和XAML, 但是在control的基础设计和实现上CLR转移到了C, 然后通过WinRT来暴露给使用者至于使用的灵活性比如要不要实现数据绑定就看上层使用者自己的选择了.

附录

下面是我研究过程中看到的一些Win8callstack. 基于这些callstack和我以往的经验才写了上面的文章.

Stack1:

Windows_UI_Immersive!`Windows::Internal::CMessageDialog::ShowAsync'::`50'::<lambda_32D66FEFF293CE6B>::<lambda_32D66FEFF293CE6B>

Windows_UI_Immersive!Windows::Internal::CMessageDialog::ShowAsync+0x1a0

image08ee0000!DomainNeutralILStubClass.IL_STUB_CLRtoCOM()+0x8c

application1!Application1.MainPage+<button_Click>d__0.MoveNext()+0xcd

application1!Application1.MainPage.button_Click(System.Object, Windows.UI.Xaml.RoutedEventArgs)+0x80

stack2:

combase!CComActivator::DoCreateInstance+0x121

combase!CoCreateInstanceEx+0x51

combase!CoCreateInstance+0x65

Windows_UI_Immersive!Windows::Internal::CPopupWindowImpl::_TryToUnregisterForIHMNotifications+0x3b

Windows_UI_Immersive!Windows::Internal::CPopupWindowImpl::_HideWindow+0x31

Windows_UI_Immersive!Windows::Internal::CPopupWindowImpl::HideWindow+0x9

Windows_UI_Immersive!Windows::Internal::CPopupWindowImpl::DestroyWindow+0x24

Windows_UI_Immersive!Windows::Internal::CPopupWindow::Destroy+0x57

Windows_UI_Immersive!Windows::Internal::CClosePopupCommandHandler::Invoke+0xe 0x73

Windows_UI_Immersive!Windows::Internal::CPopupWindowImpl::_OnButtonPress+0xc0

Windows_UI_Immersive!Windows::Internal::CPopupWindowImpl::OnMessage+0x18b

DUI70!DirectUI::NativeHWNDHost::WndProc+0x73

USER32!InternalCallWinProc+0x23

USER32!UserCallWinProcCheckWow+0x100

USER32!DispatchMessageWorker+0x3d4

USER32!DispatchMessageW+0x10

Windows_UI_Immersive!SHProcessMessagesUntilEventsEx+0xe2

Windows_UI_Immersive!Windows::Internal::PopupWindowOperation::Show+0x103

Stack3:

Windows_UI_Xaml!HWWalk::RenderChildren+0x7a

Windows_UI_Xaml!HWWalk::RenderContentAndChildren+0x2d1

Windows_UI_Xaml!HWWalk::Render+0x61e

Windows_UI_Xaml!HWWalk::RenderChildren+0x7a

Windows_UI_Xaml!HWWalk::RenderRoot+0x1c4

Windows_UI_Xaml!CCoreServices::NWDrawTree+0x698

Windows_UI_Xaml!CCoreServices::NWDraw+0x1d6

Windows_UI_Xaml!CRenderTarget::Draw+0x13

Windows_UI_Xaml!CWindowRenderTarget::Draw+0x40

Windows_UI_Xaml!CXcpBrowserHost::OnTick+0x88

Windows_UI_Xaml!CXcpDispatcher::Tick+0x184

Windows_UI_Xaml!CXcpDispatcher::OnReentrancyProtectedWindowMessage+0x133

Windows_UI_Xaml!CXcpDispatcher::ProcessMessage+0xa4

Windows_UI_Xaml!CXcpDispatcher::WindowProc+0x69

USER32!InternalCallWinProc+0x23

USER32!UserCallWinProcCheckWow+0x100

USER32!DispatchMessageWorker+0x3d4

USER32!DispatchMessageW+0x10

windows_ui!Windows::UI::Core::CDispatcher::ProcessMessage+0xc7

windows_ui!Windows::UI::Core::CDispatcher::ProcessEvents+0x6c

Windows_UI_Xaml!CJupiterWindow::RunCoreWindowMessageLoop+0x3b

Windows_UI_Xaml!CJupiterControl::RunMessageLoop+0x1d

Windows_UI_Xaml!CJupiterControlLight::RunMessageLoop+0x8

Windows_UI_Xaml!DirectUI::DXamlCore::RunMessageLoop+0x15

Windows_UI_Xaml!DirectUI::ViewProvider::Run+0x11

twinapi!Windows::ApplicationModel::Core::CoreApplicationView::ViewProviderThreadProc+0x27

分享到:
评论

相关推荐

    微软软件开发技术二十年回顾

    随着技术的不断演进,微软的开发平台也持续更新,例如Windows 7、Windows 8、Windows 10等,每个版本都引入了新的API、开发工具和编程模型,如DirectX、UWP(通用Windows平台)和Azure云服务。这些变化反映了微软对...

    回顾微软30年 Win1到Win10是如何发展演变的.doc编程资料

    回顾微软30年 Win1到Win10是如何发展演变的.doc

    win8 独有快捷键

    在探讨Windows 8独有的快捷键之前,我们先简要回顾一下Windows 8系统本身。Windows 8是微软公司于2012年发布的一款操作系统,它在用户界面、硬件兼容性和安全性方面进行了重大改进,特别是在触摸屏设备上的用户体验...

    微软公布Win10最低配置要求.docx

    ### 微软Win10最低配置要求解析 #### 一、引言 随着技术的发展与迭代,操作系统作为连接用户与硬件的重要桥梁,其版本更新往往伴随着对计算机硬件配置的新要求。2015年,微软推出了Windows 10操作系统,并在当时...

    生活与设计win8风格ppt模板.rar

    对于商业场合,Win8风格PPT模板尤其适合科技公司、数字产品推广或者与微软产品相关的展示。其现代化的界面设计能够体现公司的创新精神和技术领先的形象,帮助企业在演示中脱颖而出。此外,该模板的灵活性也使得它能...

    WIN11新版画图问题解决

    标题 "WIN11新版画图问题解决" 涉及的是在Windows 11操作系统中遇到的与默认画图应用程序(MSPaint)相关的技术问题。Windows 11是微软发布的最新一代桌面操作系统,它引入了许多界面和功能的更新。然而,随着新系统...

    win1.0~2.0

    标题“win1.0~2.0”暗示了我们正在讨论的是微软早期操作系统Windows的早期版本,从1.0到2.0。Windows是全球最广泛使用的个人计算机操作系统之一,它的历史可以追溯到1985年。这些早期版本对后来的Windows系统发展...

    Win8快速开机揭秘 混合启动(Hybrid Boot).docx

    在Windows 8系统中,微软通过引入“混合启动”(Hybrid Boot)技术大大提升了系统的开机速度,使得搭载SSD固态硬盘的Win8设备能够实现近乎瞬时的启动体验。 #### 混合启动原理 “混合启动”的核心思想是在关机时仅...

    从Windows RT到骁龙835 那些年微软—直没死心的ARM.pdf

    在Build 2017大会上,微软展示了在ARM上运行Windows 10的技术细节,包括支持通用Windows平台(UWP)应用及Win32应用程序,并通过模拟技术实现了对现有Win32应用的支持。这一突破得益于WOW层的运用,使得X86程序能在...

    Win32下的时钟程序实例源码

    在Windows编程领域,Win32 API(应用程序接口)是一个至关重要的平台,用于开发原生的Windows应用程序。这个“Win32下的时钟程序实例源码”提供了一个在Win32环境下编写简单时钟程序的示例,帮助开发者理解和实践...

    Win8PPT模板.ppt

    【标题】:“Win8PPT模板.ppt”提供的知识点 【描述】:“Win8PPT模板.ppt”可能是一个关于Windows 8操作系统的演示文稿,用于介绍该系统的特性和历史,同时也可能涉及Windows 7的一些关键信息。 【标签】:“PPT...

    微软原版教材2555A课程(带翻译)

    本课程的最后部分将回顾整个模块的关键概念和技能,强调重要的编程技巧和最佳实践,帮助学生巩固所学知识,准备应对实际工作中的技术挑战。 综上所述,微软原版教材2555A课程深入浅出地讲解了如何在.NET框架下实现...

    win10开发.pdf

    本文档《win10开发.pdf》是关于Windows 10平台开发的详细指南,覆盖了Windows 10多个版本的SDK(软件开发工具包)介绍及其使用方法。文档不仅提供了API的新增信息,还包含对开发者的指导和最新的开发者资讯。内容...

    netmeeting for win7

    然而,随着技术的迭代,NetMeeting在Windows 7之后的版本中逐渐被取代,取而代之的是更加现代化的远程协作平台如Skype for Business(现已被Microsoft Teams所取代)。 NetMeeting的核心功能包括: 1. **远程会议*...

    C#微软培训资料

    1.3 C#语言的特点.8 1.4 小 结 .11 第二章 运行环境 全面了解.NET.12 2.1 .NET 结构.12 2.2 公用语言运行时环境与公用语言规范.13 2.3 开 发 工 具 .17 2.4 小 结 .19 第三章 编写第一个应用程序 .20 ...

    罗云彬win32汇编教程(第二版)随书光盘.rar

    Win32汇编语言是针对微软Windows操作系统开发程序的基础,它允许程序员直接操作硬件,从而实现高效且低级别的编程。罗云彬的教程以通俗易懂的方式讲解了这一复杂主题,适合对计算机底层工作原理感兴趣的初学者和进阶...

    win95/98时代的经典游戏:打砖块

    《打砖块》是一款历史悠久的经典游戏,源自20...无论是在技术层面还是情感层面,它都值得我们去回顾和珍藏。通过分享和讨论,我们可以更好地理解和传承这段历史,同时也能在怀旧中找到乐趣,体验不同时代的游戏文化。

    WIN32.ISO_windows3.2_

    从这个系统开始,微软逐步完善了Windows的用户体验,使得操作系统变得更加易用和强大。 如今,Windows 3.2已成历史,但其在个人计算机发展史上的地位不可磨灭。通过模拟器或者虚拟机,我们仍然可以体验到这个古董...

    win8快捷键大全

    在深入探讨Windows 8快捷键大全之前,我们先简要回顾一下Windows 8系统的特点及其对用户的意义。Windows 8是微软于2012年发布的一款操作系统,它引入了全新的用户界面,即“Metro”界面(现更名为“Modern UI”),...

Global site tag (gtag.js) - Google Analytics