許多開發者以為 ISynchronizeInvoke 只用於 Windows Forms,其實它的應用範圍更廣。例如,一個 Calculator 類別提供 Add() 方法將兩個數字相加,內部即透過 ISynchronizeInvoke 實現。使用者必須確保 Invoke() 的呼叫發生在正確的執行緒上。
若不想進行同步呼叫,可改用 BeginInvoke() 和 EndInvoke(),遵循 .NET 標準的非同步程式設計模式(APM):以 BeginInvoke() 發送呼叫,再用 EndInvoke() 等待完成、取得回傳值或進行完成通知。特別注意的是,ISynchronizeInvoke 的方法並非型別安全——型別不符會在執行時拋出例外,而非編譯錯誤,因此使用時需格外小心,編輯器無法靜態檢查這類錯誤。
實作 ISynchronizeInvoke 需使用委派在晚期繫結中動態呼叫方法。每種委派類型皆提供 DynamicInvoke(object[] args) 方法。理論上,必須將方法委派置於執行目標物件的真實執行緒中,讓 Invoke() 和 BeginInvoke() 內部的委派呼叫 DynamicInvoke()。
ISynchronizeInvoke 的實作是一項進階程式技巧。隨附原始碼提供了 Synchronizer 輔助類別(為 ISynchronizeInvoke 的通用實作)與測試程式,示範 Calculator 如何透過 Synchronizer 實作介面。Synchronizer 可直接使用或衍生。
核心元素是巢狀類別 WorkerThread,內含工作項目佇列。WorkItem 封裝方法委派與參數。Invoke() 與 BeginInvoke() 將工作項目加入佇列。WorkerThread 建立 .NET 背景執行緒,輪詢佇列、取出項目並呼叫 DynamicInvoke() 執行。
將 HTML 內容放入剪貼簿供其他應用程式使用,需遵循 CF_HTML 格式。此格式為註冊格式(非預設常數),其數值隨系統而異,須呼叫 RegisterClipboardFormat("Html Format") 取得唯一識別碼(範圍 C000-FFFF)。
將 HTML 資料放入剪貼簿前,必須先建構 Header,提供版本、HTML 起始/結束位移、實際選取片段的起始/結束位移:
Version:1.0
StartHtml:000000258
EndHtml:000001491
StartFragment:000001172
EndFragment:000001411
應用程式依 StartFragment 和 EndFragment 決定貼上內容。需在 HTML 資料中插入註解標記 <!--StartFragment--> 和 <!--EndFragment--> 標識選取區域。Header 的位移為零基底,字串操作須配合調整;不同應用(IE 9 位數、Word 10 位數)位移寬度不同。
僅放入 CF_HTML 會導致 Word、FrontPage 等無法處理。必須同時提供格式化 HTML 的純文字轉譯。可善用 OS 內建 Htmlfile 物件自動轉換:
Public Function Html2Text(ByVal Data As String) As String
Dim obj As Object
On Error Resume Next
Set obj = CreateObject("Htmlfile")
obj.Open
obj.Write Data
Html2Text = obj.Body.InnerText
End Function
雖非最快,但相當好用。