<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      代碼改變世界

      從Win8回顧微軟平臺的各種技術

      2011-12-03 14:15  lixiong  閱讀(13463)  評論(49)    收藏  舉報

      我安裝好Win8 CTP后做的第一件事情就是用調試器研究Win8各個組件的協作關系. 從我半天的研究結果看來, Win8真是一個讓我愛不釋手的產品. Win8里面涉及到的很多技術正好也是我的興趣所在. 這篇文章簡單回顧一下這些技術的變遷, 優缺點, 和對Win8的影響.

      注意, 下面提到的對Win8的分析, 是基于公開的Win8 CTP來做的. 相信Win8面世的時候, 這些技術和細節, 都會發生重大改變. 所以這篇文章不具備實踐上的指導價值.

      COM -Component 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

      This is the end

       

      主站蜘蛛池模板: 国产无套乱子伦精彩是白视频| 极品少妇的粉嫩小泬看片| 亚洲精品一区二区制服| 18禁男女爽爽爽午夜网站免费| caoporn免费视频公开| 久久精品伊人狠狠大香网| 麻豆成人传媒一区二区| 制服 丝袜 亚洲 中文 综合| 麻豆一区二区三区香蕉视频| 美女自卫慰黄网站| 欧美人与性动交α欧美精品| 日韩老熟女av搜索结果| 视频免费完整版在线播放| 中文字幕免费不卡二区| 久久96热在精品国产高清| 欧美激情一区二区久久久| 亚洲高清无在码在线无弹窗| xxxx丰满少妇高潮| 久久久国产成人一区二区 | 中文字幕第一页国产| 精品国产美女福到在线不卡| 石渠县| 亚洲国产一区二区三区四| 人人澡人摸人人添| 石林| 人妻少妇| 国产成人久久精品流白浆| 安庆市| 亚洲男人在线天堂| 人妻中出无码中字在线| 成人免费A级毛片无码片2022| 狠狠干| 欧美交A欧美精品喷水| 深夜免费av在线观看| 国内精品视频区在线2021| 大帝AV在线一区二区三区| 国产一区二区三区av在线无码观看| AV无码不卡一区二区三区| 国产高潮刺激叫喊视频| 在线免费成人亚洲av| 色综合久久婷婷88|