Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Dalam sebagian besar kasus, instans kelas Windows Runtime dapat diakses dari utas apa pun (seperti kebanyakan objek C++ standar). Kelas Windows Runtime seperti itu tangkas. Hanya sejumlah kecil kelas Windows Runtime yang disertakan dalam Windows bersifat non-agile, tetapi saat Anda menggunakannya, Anda perlu mempertimbangkan model threading dan perilaku marshaling-nya (marshaling adalah proses meneruskan data melintasi batas apartment). Merupakan setelan bawaan yang baik jika setiap objek Windows Runtime bersifat agile, sehingga tipe C++/WinRT Anda sendiri juga bersifat agile secara bawaan.
Tetapi Anda dapat memilih keluar. Anda mungkin memiliki alasan kuat untuk mengharuskan objek jenis Anda berada, misalnya, di apartemen berulir tunggal tertentu. Ini biasanya ada hubungannya dengan persyaratan reentrancy. Namun, kini bahkan semakin banyak API antarmuka pengguna (UI) yang menawarkan objek yang lincah. Secara umum, kelincahan adalah opsi yang paling sederhana dan paling berkinerja. Selain itu, ketika Anda mengimplementasikan pabrik aktivasi, pabrik tersebut harus bersifat agile meskipun kelas runtime terkait tidak.
Note
Windows Runtime didasarkan pada COM. Dalam istilah COM, kelas agile didaftarkan dengan ThreadingModel = Both. Untuk informasi selengkapnya tentang model threading COM dan apartment, lihat Memahami dan Menggunakan Model Threading COM.
Contoh kode
Mari kita gunakan contoh implementasi kelas runtime untuk menunjukkan bagaimana C++/WinRT mendukung kelincahan.
#include <winrt/Windows.Foundation.h>
using namespace winrt;
using namespace Windows::Foundation;
struct MyType : winrt::implements<MyType, IStringable>
{
winrt::hstring ToString(){ ... }
};
Karena kami tidak menolak ikut, implementasi ini fleksibel. Struktur dasar winrt::implements mengimplementasikan IAgileObject dan IMarshal. Implementasi IMarshal menggunakan CoCreateFreeThreadedMarshaler untuk melakukan hal yang benar untuk kode warisan yang tidak tahu tentang IAgileObject.
Kode ini memeriksa objek untuk kelincahan. Panggilan ke IUnknown::as menghasilkan pengecualian jika myimpl tidak agile.
winrt::com_ptr<MyType> myimpl{ winrt::make_self<MyType>() };
winrt::com_ptr<IAgileObject> iagileobject{ myimpl.as<IAgileObject>() };
Daripada menangani pengecualian, Anda dapat memanggil IUnknown::try_as sebagai gantinya.
winrt::com_ptr<IAgileObject> iagileobject{ myimpl.try_as<IAgileObject>() };
if (iagileobject) { /* myimpl is agile. */ }
IAgileObject tidak memiliki metodenya sendiri, sehingga Anda tidak dapat melakukan banyak hal dengannya. Varian berikutnya, maka, lebih khas.
if (myimpl.try_as<IAgileObject>()) { /* myimpl is agile. */ }
IAgileObject adalah antarmuka penanda. Keberhasilan atau kegagalan semata dari melakukan kueri terhadap IAgileObject adalah seluruh informasi dan manfaat yang bisa Anda peroleh darinya.
Nonaktifkan dukungan agile object
Anda dapat secara eksplisit memilih untuk tidak menggunakan dukungan objek agile dengan memberikan struct penanda winrt::non_agile sebagai argumen templat ke kelas dasar Anda.
Jika Anda memperoleh langsung dari winrt::implements.
struct MyImplementation: implements<MyImplementation, IStringable, winrt::non_agile>
{
...
}
Jika Anda membuat kelas runtime.
struct MyRuntimeClass: MyRuntimeClassT<MyRuntimeClass, winrt::non_agile>
{
...
}
Tidak masalah di mana dalam paket parameter variadik struktur penanda muncul.
Terlepas dari apakah Anda memilih untuk tidak menggunakan agility atau tidak, Anda dapat mengimplementasikan IMarshal sendiri. Misalnya, Anda dapat menggunakan penanda winrt::non_agile untuk menghindari implementasi kelincahan default, dan mengimplementasikan IMarshal sendiri—mungkin untuk mendukung semantik marshal-by-value.
Referensi agile (winrt::agile_ref)
Jika Anda menggunakan objek yang tidak agile, tetapi perlu meneruskannya dalam konteks yang mungkin memerlukan objek agile, maka salah satu opsinya adalah menggunakan templat struktur winrt::agile_ref untuk mendapatkan referensi agile ke instans tipe non-agile, atau ke antarmuka dari objek non-agile.
NonAgileType nonagile_obj;
winrt::agile_ref<NonAgileType> agile{ nonagile_obj };
Atau, Anda dapat menggunakan fungsi pembantu winrt::make_agile .
NonAgileType nonagile_obj;
auto agile{ winrt::make_agile(nonagile_obj) };
Dalam kedua kasus, agile sekarang dapat dengan bebas diteruskan ke utas di apartemen yang berbeda, dan digunakan di sana.
co_await resume_background();
NonAgileType nonagile_obj_again{ agile.get() };
winrt::hstring message{ nonagile_obj_again.Message() };
Panggilan agile_ref::get mengembalikan proksi yang dapat digunakan dengan aman dalam konteks utas tempat get dipanggil.
API penting
- Antarmuka IAgileObject
- Antarmuka IMarshal
- winrt::agile_ref struct template
- winrt::mengimplementasikan templat struct
- templat fungsi winrt::make_agile
- winrt::non_agile struct penanda
- winrt::Windows::Foundation::IUnknown::as function
- winrt::Windows::Foundation::IUnknown::try_as function
Topik terkait
Windows developer