使用 C#/WinRT 的敏捷式物件

大部分的 Windows 執行階段類別都是敏捷的,這表示可以從不同 Apartment 的任何執行緒加以存取。 您撰寫的 C#/WinRT 類型預設為敏捷式,因此無法針對這些類型退出宣告此行為。

不過,投影的 C#/WinRT 類型 (包括 Windows SDK 和 WinUI 程式庫所提供的 Windows 執行階段類型) 不一定會是敏捷式。 例如,代表 UI 物件的許多類型並不敏捷。 當您取用非敏捷式類型時,您必須考慮其執行緒模型和封送處理行為。 如果您需要以安全的方式跨 Apartment 封送處理非敏捷式物件,C#/WinRT 提供敏捷式參考的支援。

注意

Windows 執行階段是以 COM 為基礎。 在 COM 條款中,會向 ThreadingModel = Both 註冊敏捷式類別。 如需有關 COM 執行緒模式和 Apartment 的詳細資訊,請參閱了解與使用 COM 執行緒模式

檢查敏捷式支援

若要檢查 Windows 執行階段物件是否敏捷,請使用下列程式碼來判斷物件是否支援 IAgileObject 介面。

var queryAgileObject = testObject.As<IAgileObject>();

if (queryAgileObject != null) {
    // testObject is agile.
}

建立敏捷式參考

若要建立非敏捷式物件的敏捷式參考,您可以使用 AsAgile 擴充方法。 AsAgile 是泛型擴充方法,可以套用至任何投影的 C#/WinRT 類型。 如果類型不是投影類型,則會擲回例外狀況。 以下是使用 PopupMenu 物件的範例,這是來自 Windows SDK 的非敏捷式類型。

var nonAgileObj = new Windows.UI.Popups.PopupMenu();
AgileReference<Windows.UI.Popups.PopupMenu> agileReference = nonAgileObj.AsAgile();

您現在可以在不同的 Apartment 中傳遞 agileReference 至執行緒,並在該處使用它。

await Task.Run(() => {
        Windows.UI.Popups.PopupMenu nonAgileObjAgain = agileReference.Get();
    });