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.
Catatan
Topik ini ada untuk membantu Anda mempertahankan aplikasi C++/CX Anda. Tetapi kami sarankan Anda menggunakan C++/WinRT untuk aplikasi baru. C++/WinRT adalah proyeksi bahasa C++17 modern yang sepenuhnya standar untuk API Windows Runtime (WinRT), yang diimplementasikan sebagai pustaka berbasis file header, dan dirancang untuk memberi Anda akses kelas satu ke Windows API modern. Untuk mempelajari cara membuat komponen Windows Runtime menggunakan C++/WinRT, lihat komponen Windows Runtime dengan C++/WinRT.
Panduan ini menunjukkan cara membuat DLL komponen Windows Runtime dasar yang dapat dipanggil dari JavaScript, C#, atau Visual Basic. Sebelum memulai panduan ini, pastikan Anda memahami konsep seperti Antarmuka Biner Abstrak (ABI), kelas ref, dan Ekstensi Komponen Visual C++ yang mempermudah bekerja dengan kelas ref. Untuk informasi selengkapnya, lihat Komponen Windows Runtime dengan C++/CX dan Referensi Bahasa Visual C++ (C++/CX).
Membuat DLL komponen C++
Dalam contoh ini, kami membuat proyek komponen terlebih dahulu, tetapi Anda dapat membuat proyek JavaScript terlebih dahulu. Pesanan tidak masalah.
Perhatikan bahwa kelas utama komponen berisi contoh definisi properti dan metode, dan deklarasi peristiwa. Ini disediakan hanya untuk menunjukkan kepada Anda bagaimana hal itu dilakukan. Mereka tidak diperlukan, dan dalam contoh ini, kita akan mengganti semua kode yang dihasilkan dengan kode kita sendiri.
Untuk membuat proyek komponen C++
Pada bilah menu Visual Studio, pilih File, Baru, Proyek.
Dalam kotak dialog Proyek Baru, di panel kiri, perluas Visual C++ lalu pilih simpul untuk aplikasi Universal Windows.
Di panel tengah, pilih Komponen Runtime Windows lalu beri nama proyek WinRT_CPP.
Pilih tombol OK.
Untuk menambahkan kelas yang dapat diaktifkan ke komponen
Kelas yang dapat diaktifkan adalah kelas yang dapat dibuat kode klien dengan menggunakan ekspresi baru (Baru di Visual Basic, atau ref baru di C++). Dalam komponen Anda, Anda menyatakannya sebagai kelas ref publik yang disegel. Bahkan, file Class1.h dan .cpp sudah memiliki kelas ref. Anda dapat mengubah nama, tetapi dalam contoh ini kita akan menggunakan nama default—Class1. Anda dapat menentukan kelas ref tambahan atau kelas reguler di komponen Anda jika diperlukan. Untuk informasi selengkapnya tentang kelas ref, lihat Sistem Tipe (C++/CX).
Tambahkan direktif #include ini ke Class1.h:
#include <collection.h>
#include <ppl.h>
#include <amp.h>
#include <amp_math.h>
collection.h adalah file header untuk kelas konkret C++ seperti kelas Platform::Collections::Vector dan kelas Platform::Collections::Map, yang mengimplementasikan antarmuka netral bahasa yang ditentukan oleh Windows Runtime. Header amp digunakan untuk menjalankan komputasi pada GPU. Mereka tidak memiliki ekuivalen Windows Runtime, dan itu baik-baik saja karena bersifat privat. Secara umum, untuk alasan performa, Anda harus menggunakan kode ISO C++ dan pustaka standar secara internal dalam komponen; ini hanya antarmuka Windows Runtime yang harus diekspresikan dalam jenis Windows Runtime.
Untuk menambahkan delegasi di cakupan namespace
Delegasi adalah konstruksi yang menentukan parameter dan jenis pengembalian untuk metode. Peristiwa adalah instans jenis delegasi tertentu, dan metode penanganan aktivitas apa pun yang berlangganan peristiwa harus memiliki tanda tangan yang ditentukan dalam delegasi. Kode berikut mendefinisikan jenis delegasi yang mengambil int dan mengembalikan kekosongan. Selanjutnya kode mendeklarasikan peristiwa publik jenis ini; ini memungkinkan kode klien untuk menyediakan metode yang dipanggil saat peristiwa dipicu.
Tambahkan deklarasi delegasi berikut pada cakupan namespace di Class1.h, tepat sebelum deklarasi Class1.
public delegate void PrimeFoundHandler(int result);
Jika kode tidak dibariskan dengan benar saat Anda menempelkannya ke Visual Studio, cukup tekan Ctrl+K+D untuk memperbaiki indentasi untuk seluruh file.
Untuk menambahkan anggota publik
Kelas ini mengekspos tiga metode publik dan satu acara publik. Metode pertama sinkron karena selalu dijalankan dengan sangat cepat. Karena dua metode lainnya mungkin memakan waktu, metode tersebut tidak sinkron sehingga tidak memblokir utas UI. Metode ini mengembalikan IAsyncOperationWithProgress dan IAsyncActionWithProgress. Yang pertama mendefinisikan metode asinkron yang mengembalikan hasil, dan yang terakhir mendefinisikan metode asinkron yang mengembalikan kekosongan. Antarmuka ini juga memungkinkan kode klien untuk menerima pembaruan tentang kemajuan operasi.
public:
// Synchronous method.
Windows::Foundation::Collections::IVector<double>^ ComputeResult(double input);
// Asynchronous methods
Windows::Foundation::IAsyncOperationWithProgress<Windows::Foundation::Collections::IVector<int>^, double>^
GetPrimesOrdered(int first, int last);
Windows::Foundation::IAsyncActionWithProgress<double>^ GetPrimesUnordered(int first, int last);
// Event whose type is a delegate "class"
event PrimeFoundHandler^ primeFoundEvent;
Untuk menambahkan anggota privat
Kelas berisi tiga anggota privat: dua metode pembantu untuk komputasi numerik dan objek CoreDispatcher yang digunakan untuk marsekal pemanggilan peristiwa dari utas pekerja kembali ke utas UI.
private:
bool is_prime(int n);
Windows::UI::Core::CoreDispatcher^ m_dispatcher;
Untuk menambahkan direktif header dan namespace
- Di Class1.cpp, tambahkan arahan #include ini:
#include <ppltasks.h>
#include <concurrent_vector.h>
- Sekarang tambahkan ini menggunakan pernyataan untuk menarik namespace yang diperlukan:
using namespace concurrency;
using namespace Platform::Collections;
using namespace Windows::Foundation::Collections;
using namespace Windows::Foundation;
using namespace Windows::UI::Core;
Untuk menambahkan implementasi untuk ComputeResult
Dalam Class1.cpp, tambahkan implementasi metode berikut. Metode ini dijalankan secara sinkron pada utas panggilan, tetapi sangat cepat karena menggunakan C++ AMP untuk menyejajarkan komputasi pada GPU. Untuk informasi selengkapnya, lihat Gambaran Umum C++ AMP. Hasilnya ditambahkan ke jenis beton Platform::Collections::Vector<T> , yang secara implisit dikonversi ke Windows::Foundation::Collections::IVector<T> ketika dikembalikan.
//Public API
IVector<double>^ Class1::ComputeResult(double input)
{
// Implement your function in ISO C++ or
// call into your C++ lib or DLL here. This example uses AMP.
float numbers[] = { 1.0, 10.0, 60.0, 100.0, 600.0, 10000.0 };
array_view<float, 1> logs(6, numbers);
// See http://msdn.microsoft.com/library/hh305254.aspx
parallel_for_each(
logs.extent,
[=] (index<1> idx) restrict(amp)
{
logs[idx] = concurrency::fast_math::log10(logs[idx]);
}
);
// Return a Windows Runtime-compatible type across the ABI
auto res = ref new Vector<double>();
int len = safe_cast<int>(logs.extent.size());
for(int i = 0; i < len; i++)
{
res->Append(logs[i]);
}
// res is implicitly cast to IVector<double>
return res;
}
Untuk menambahkan implementasi untuk GetPrimesOrdered dan metode pembantunya
Dalam Class1.cpp, tambahkan implementasi untuk GetPrimesOrdered dan metode pembantu is_prime. GetPrimesOrdered menggunakan kelas concurrent_vector dan perulangan fungsi parallel_for untuk membagi pekerjaan dan menggunakan sumber daya maksimum komputer tempat program berjalan untuk menghasilkan hasil. Setelah hasilnya dihitung, disimpan, dan diurutkan, hasilnya ditambahkan ke Platform::Collections::Vector<T> dan dikembalikan sebagai Windows::Foundation::Collections::IVector<T> ke kode klien.
Perhatikan kode untuk reporter kemajuan, yang memungkinkan klien untuk menghubungkan bilah kemajuan atau antarmuka pengguna lain untuk menunjukkan kepada pengguna berapa lama lagi operasi akan berlangsung. Pelaporan kemajuan memiliki biaya. Peristiwa harus diaktifkan di sisi komponen dan ditangani pada utas UI, dan nilai kemajuan harus disimpan pada setiap perulangan. Salah satu cara untuk meminimalkan biaya adalah dengan membatasi frekuensi peristiwa kemajuan dipicu. Jika biaya masih melarang, atau jika Anda tidak dapat memperkirakan lamanya operasi, maka pertimbangkan untuk menggunakan cincin kemajuan, yang menunjukkan bahwa operasi sedang berlangsung tetapi tidak menunjukkan waktu yang tersisa hingga selesai.
// Determines whether the input value is prime.
bool Class1::is_prime(int n)
{
if (n < 2)
return false;
for (int i = 2; i < n; ++i)
{
if ((n % i) == 0)
return false;
}
return true;
}
// This method computes all primes, orders them, then returns the ordered results.
IAsyncOperationWithProgress<IVector<int>^, double>^ Class1::GetPrimesOrdered(int first, int last)
{
return create_async([this, first, last]
(progress_reporter<double> reporter) -> IVector<int>^ {
// Ensure that the input values are in range.
if (first < 0 || last < 0) {
throw ref new InvalidArgumentException();
}
// Perform the computation in parallel.
concurrent_vector<int> primes;
long operation = 0;
long range = last - first + 1;
double lastPercent = 0.0;
parallel_for(first, last + 1, [this, &primes, &operation,
range, &lastPercent, reporter](int n) {
// Increment and store the number of times the parallel
// loop has been called on all threads combined. There
// is a performance cost to maintaining a count, and
// passing the delegate back to the UI thread, but it's
// necessary if we want to display a determinate progress
// bar that goes from 0 to 100%. We can avoid the cost by
// setting the ProgressBar IsDeterminate property to false
// or by using a ProgressRing.
if(InterlockedIncrement(&operation) % 100 == 0)
{
reporter.report(100.0 * operation / range);
}
// If the value is prime, add it to the local vector.
if (is_prime(n)) {
primes.push_back(n);
}
});
// Sort the results.
std::sort(begin(primes), end(primes), std::less<int>());
reporter.report(100.0);
// Copy the results to a Vector object, which is
// implicitly converted to the IVector return type. IVector
// makes collections of data available to other
// Windows Runtime components.
return ref new Vector<int>(primes.begin(), primes.end());
});
}
Untuk menambahkan implementasi untuk GetPrimesUnordered
Langkah terakhir untuk membuat komponen C++ adalah menambahkan implementasi untuk GetPrimesUnordered di Class1.cpp. Metode ini mengembalikan setiap hasil seperti yang ditemukan, tanpa menunggu sampai semua hasil ditemukan. Setiap hasil dikembalikan dalam penanganan aktivitas dan ditampilkan pada UI secara real time. Sekali lagi, perhatikan bahwa reporter kemajuan digunakan. Metode ini juga menggunakan metode pembantu is_prime.
// This method returns no value. Instead, it fires an event each time a
// prime is found, and passes the prime through the event.
// It also passes progress info.
IAsyncActionWithProgress<double>^ Class1::GetPrimesUnordered(int first, int last)
{
auto window = Windows::UI::Core::CoreWindow::GetForCurrentThread();
m_dispatcher = window->Dispatcher;
return create_async([this, first, last](progress_reporter<double> reporter) {
// Ensure that the input values are in range.
if (first < 0 || last < 0) {
throw ref new InvalidArgumentException();
}
// In this particular example, we don't actually use this to store
// results since we pass results one at a time directly back to
// UI as they are found. However, we have to provide this variable
// as a parameter to parallel_for.
concurrent_vector<int> primes;
long operation = 0;
long range = last - first + 1;
double lastPercent = 0.0;
// Perform the computation in parallel.
parallel_for(first, last + 1,
[this, &primes, &operation, range, &lastPercent, reporter](int n)
{
// Store the number of times the parallel loop has been called
// on all threads combined. See comment in previous method.
if(InterlockedIncrement(&operation) % 100 == 0)
{
reporter.report(100.0 * operation / range);
}
// If the value is prime, pass it immediately to the UI thread.
if (is_prime(n))
{
// Since this code is probably running on a worker
// thread, and we are passing the data back to the
// UI thread, we have to use a CoreDispatcher object.
m_dispatcher->RunAsync( CoreDispatcherPriority::Normal,
ref new DispatchedHandler([this, n, operation, range]()
{
this->primeFoundEvent(n);
}, Platform::CallbackContext::Any));
}
});
reporter.report(100.0);
});
}
Membuat aplikasi klien JavaScript (Visual Studio 2017)
Jika Anda ingin membuat klien C#, maka Anda dapat melewati bagian ini.
Catatan
proyek Platform Windows Universal (UWP) yang menggunakan JavaScript tidak didukung di Visual Studio 2019. Lihat JavaScript dan TypeScript di Visual Studio 2019. Untuk mengikuti bagian ini, kami sarankan Anda menggunakan Visual Studio 2017. Lihat JavaScript di Visual Studio 2017.
Untuk membuat proyek JavaScript
Di Penjelajah Solusi (di Visual Studio 2017; lihat Catatan di atas), buka menu pintasan untuk node Solusi dan pilih Tambahkan, Proyek Baru.
Perluas JavaScript (mungkin disarangkan di bawah Bahasa Lain) dan pilih Aplikasi Kosong (Universal Windows).
Terima nama default—App1—dengan memilih tombol OK .
Buka menu pintasan untuk simpul proyek App1 dan pilih Atur sebagai Proyek Startup.
Tambahkan referensi proyek ke WinRT_CPP:
Buka menu pintasan untuk simpul Referensi dan pilih Tambahkan Referensi.
Di panel kiri kotak dialog Manajer Referensi, pilih Proyek lalu pilih Solusi.
Di panel tengah, pilih WinRT_CPP lalu pilih tombol OK
Untuk menambahkan HTML yang memanggil penanganan aktivitas JavaScript
Tempelkan HTML ini ke dalam <simpul isi> halaman default.html:
<div id="LogButtonDiv">
<button id="logButton">Logarithms using AMP</button>
</div>
<div id="LogResultDiv">
<p id="logResult"></p>
</div>
<div id="OrderedPrimeButtonDiv">
<button id="orderedPrimeButton">Primes using parallel_for with sort</button>
</div>
<div id="OrderedPrimeProgress">
<progress id="OrderedPrimesProgressBar" value="0" max="100"></progress>
</div>
<div id="OrderedPrimeResultDiv">
<p id="orderedPrimes">
Primes found (ordered):
</p>
</div>
<div id="UnorderedPrimeButtonDiv">
<button id="ButtonUnordered">Primes returned as they are produced.</button>
</div>
<div id="UnorderedPrimeDiv">
<progress id="UnorderedPrimesProgressBar" value="0" max="100"></progress>
</div>
<div id="UnorderedPrime">
<p id="unorderedPrimes">
Primes found (unordered):
</p>
</div>
<div id="ClearDiv">
<button id="Button_Clear">Clear</button>
</div>
Untuk menambahkan gaya
Di default.css, hapus gaya isi lalu tambahkan gaya ini:
#LogButtonDiv {
border: orange solid 1px;
-ms-grid-row: 1; /* default is 1 */
-ms-grid-column: 1; /* default is 1 */
}
#LogResultDiv {
background: black;
border: red solid 1px;
-ms-grid-row: 1;
-ms-grid-column: 2;
}
#UnorderedPrimeButtonDiv, #OrderedPrimeButtonDiv {
border: orange solid 1px;
-ms-grid-row: 2;
-ms-grid-column:1;
}
#UnorderedPrimeProgress, #OrderedPrimeProgress {
border: red solid 1px;
-ms-grid-column-span: 2;
height: 40px;
}
#UnorderedPrimeResult, #OrderedPrimeResult {
border: red solid 1px;
font-size:smaller;
-ms-grid-row: 2;
-ms-grid-column: 3;
-ms-overflow-style:scrollbar;
}
Untuk menambahkan penanganan aktivitas JavaScript yang memanggil ke DLL komponen
Tambahkan fungsi berikut di akhir file default.js. Fungsi-fungsi ini dipanggil ketika tombol di halaman utama dipilih. Perhatikan bagaimana JavaScript mengaktifkan kelas C++, lalu memanggil metodenya dan menggunakan nilai pengembalian untuk mengisi label HTML.
var nativeObject = new WinRT_CPP.Class1();
function LogButton_Click() {
var val = nativeObject.computeResult(0);
var result = "";
for (i = 0; i < val.length; i++) {
result += val[i] + "<br/>";
}
document.getElementById('logResult').innerHTML = result;
}
function ButtonOrdered_Click() {
document.getElementById('orderedPrimes').innerHTML = "Primes found (ordered): ";
nativeObject.getPrimesOrdered(2, 10000).then(
function (v) {
for (var i = 0; i < v.length; i++)
document.getElementById('orderedPrimes').innerHTML += v[i] + " ";
},
function (error) {
document.getElementById('orderedPrimes').innerHTML += " " + error.description;
},
function (p) {
var progressBar = document.getElementById("OrderedPrimesProgressBar");
progressBar.value = p;
});
}
function ButtonUnordered_Click() {
document.getElementById('unorderedPrimes').innerHTML = "Primes found (unordered): ";
nativeObject.onprimefoundevent = handler_unordered;
nativeObject.getPrimesUnordered(2, 10000).then(
function () { },
function (error) {
document.getElementById("unorderedPrimes").innerHTML += " " + error.description;
},
function (p) {
var progressBar = document.getElementById("UnorderedPrimesProgressBar");
progressBar.value = p;
});
}
var handler_unordered = function (n) {
document.getElementById('unorderedPrimes').innerHTML += n.target.toString() + " ";
};
function ButtonClear_Click() {
document.getElementById('logResult').innerHTML = "";
document.getElementById("unorderedPrimes").innerHTML = "";
document.getElementById('orderedPrimes').innerHTML = "";
document.getElementById("UnorderedPrimesProgressBar").value = 0;
document.getElementById("OrderedPrimesProgressBar").value = 0;
}
Tambahkan kode untuk menambahkan pendengar peristiwa dengan mengganti panggilan yang ada ke WinJS.UI.processSemua di app.onactivated di default.js dengan kode berikut yang mengimplementasikan pendaftaran peristiwa di blokir lalu. Untuk penjelasan terperinci tentang hal ini, lihat Membuat aplikasi "Hello, World" (JS).
args.setPromise(WinJS.UI.processAll().then( function completed() {
var logButton = document.getElementById("logButton");
logButton.addEventListener("click", LogButton_Click, false);
var orderedPrimeButton = document.getElementById("orderedPrimeButton");
orderedPrimeButton.addEventListener("click", ButtonOrdered_Click, false);
var buttonUnordered = document.getElementById("ButtonUnordered");
buttonUnordered.addEventListener("click", ButtonUnordered_Click, false);
var buttonClear = document.getElementById("Button_Clear");
buttonClear.addEventListener("click", ButtonClear_Click, false);
}));
Tekan F5 untuk menjalankan aplikasi.
Membuat aplikasi klien C#
Untuk membuat proyek C#
Di Penjelajah Solusi, buka menu pintasan untuk simpul Solusi lalu pilih Tambahkan, Proyek Baru.
Perluas Visual C# (mungkin disarangkan di bawah Bahasa Lain), pilih Windows lalu Universal di panel kiri, lalu pilih Aplikasi Kosong di panel tengah.
Beri nama aplikasi ini CS_Client lalu pilih tombol OK .
Buka menu pintasan untuk simpul proyek CS_Client dan pilih Atur sebagai Proyek Startup.
Tambahkan referensi proyek ke WinRT_CPP:
Buka menu pintasan untuk simpul Referensi dan pilih Tambahkan Referensi.
Di panel kiri kotak dialog Manajer Referensi, pilih Proyek lalu pilih Solusi.
Di panel tengah, pilih WinRT_CPP lalu pilih tombol OK .
Untuk menambahkan XAML yang menentukan antarmuka pengguna
Salin kode berikut ke elemen Grid di MainPage.xaml.
<ScrollViewer>
<StackPanel Width="1400">
<Button x:Name="Button1" Width="340" Height="50" Margin="0,20,20,20" Content="Synchronous Logarithm Calculation" FontSize="16" Click="Button1_Click_1"/>
<TextBlock x:Name="Result1" Height="100" FontSize="14"></TextBlock>
<Button x:Name="PrimesOrderedButton" Content="Prime Numbers Ordered" FontSize="16" Width="340" Height="50" Margin="0,20,20,20" Click="PrimesOrderedButton_Click_1"></Button>
<ProgressBar x:Name="PrimesOrderedProgress" IsIndeterminate="false" Height="40"></ProgressBar>
<TextBlock x:Name="PrimesOrderedResult" MinHeight="100" FontSize="10" TextWrapping="Wrap"></TextBlock>
<Button x:Name="PrimesUnOrderedButton" Width="340" Height="50" Margin="0,20,20,20" Click="PrimesUnOrderedButton_Click_1" Content="Prime Numbers Unordered" FontSize="16"></Button>
<ProgressBar x:Name="PrimesUnOrderedProgress" IsIndeterminate="false" Height="40" ></ProgressBar>
<TextBlock x:Name="PrimesUnOrderedResult" MinHeight="100" FontSize="10" TextWrapping="Wrap"></TextBlock>
<Button x:Name="Clear_Button" Content="Clear" HorizontalAlignment="Left" Margin="0,20,20,20" VerticalAlignment="Top" Width="341" Click="Clear_Button_Click" FontSize="16"/>
</StackPanel>
</ScrollViewer>
Untuk menambahkan penanganan aktivitas untuk tombol
Di Penjelajah Solusi, buka MainPage.xaml.cs. (File mungkin disarangkan di bawah MainPage.xaml.) Tambahkan direktif penggunaan untuk System.Text, lalu tambahkan penanganan aktivitas untuk perhitungan Logaritma di kelas MainPage.
private void Button1_Click_1(object sender, RoutedEventArgs e)
{
// Create the object
var nativeObject = new WinRT_CPP.Class1();
// Call the synchronous method. val is an IList that
// contains the results.
var val = nativeObject.ComputeResult(0);
StringBuilder result = new StringBuilder();
foreach (var v in val)
{
result.Append(v).Append(System.Environment.NewLine);
}
this.Result1.Text = result.ToString();
}
Tambahkan penanganan aktivitas untuk hasil yang diurutkan:
async private void PrimesOrderedButton_Click_1(object sender, RoutedEventArgs e)
{
var nativeObject = new WinRT_CPP.Class1();
StringBuilder sb = new StringBuilder();
sb.Append("Primes found (ordered): ");
PrimesOrderedResult.Text = sb.ToString();
// Call the asynchronous method
var asyncOp = nativeObject.GetPrimesOrdered(2, 100000);
// Before awaiting, provide a lambda or named method
// to handle the Progress event that is fired at regular
// intervals by the asyncOp object. This handler updates
// the progress bar in the UI.
asyncOp.Progress = (asyncInfo, progress) =>
{
PrimesOrderedProgress.Value = progress;
};
// Wait for the operation to complete
var asyncResult = await asyncOp;
// Convert the results to strings
foreach (var result in asyncResult)
{
sb.Append(result).Append(" ");
}
// Display the results
PrimesOrderedResult.Text = sb.ToString();
}
Tambahkan penanganan aktivitas untuk hasil yang tidak diurutkan, dan untuk tombol yang menghapus hasilnya sehingga Anda dapat menjalankan kode lagi.
private void PrimesUnOrderedButton_Click_1(object sender, RoutedEventArgs e)
{
var nativeObject = new WinRT_CPP.Class1();
StringBuilder sb = new StringBuilder();
sb.Append("Primes found (unordered): ");
PrimesUnOrderedResult.Text = sb.ToString();
// primeFoundEvent is a user-defined event in nativeObject
// It passes the results back to this thread as they are produced
// and the event handler that we define here immediately displays them.
nativeObject.primeFoundEvent += (n) =>
{
sb.Append(n.ToString()).Append(" ");
PrimesUnOrderedResult.Text = sb.ToString();
};
// Call the async method.
var asyncResult = nativeObject.GetPrimesUnordered(2, 100000);
// Provide a handler for the Progress event that the asyncResult
// object fires at regular intervals. This handler updates the progress bar.
asyncResult.Progress += (asyncInfo, progress) =>
{
PrimesUnOrderedProgress.Value = progress;
};
}
private void Clear_Button_Click(object sender, RoutedEventArgs e)
{
PrimesOrderedProgress.Value = 0;
PrimesUnOrderedProgress.Value = 0;
PrimesUnOrderedResult.Text = "";
PrimesOrderedResult.Text = "";
Result1.Text = "";
}
Menjalankan aplikasi
Pilih proyek C# atau proyek JavaScript sebagai proyek startup dengan membuka menu pintasan untuk simpul proyek di Penjelajah Solusi dan memilih Atur Sebagai Proyek Startup. Kemudian tekan F5 untuk menjalankan dengan penelusuran kesalahan, atau Ctrl+F5 untuk berjalan tanpa penelusuran kesalahan.
Memeriksa komponen Anda di Browser Objek (opsional)
Di Browser Objek, Anda dapat memeriksa semua jenis Windows Runtime yang ditentukan dalam file .winmd. Ini termasuk jenis di namespace platform dan namespace default. Namun, karena jenis di namespace layanan Platform::Collections didefinisikan dalam file header collections.h, bukan dalam file winmd, mereka tidak muncul di Object Browser.
Untuk memeriksa komponen
Pada bilah menu, pilih Tampilan, Browser Objek (Ctrl+Alt+J).
Di panel kiri Browser Objek, perluas simpul WinRT_CPP untuk memperlihatkan jenis dan metode yang ditentukan pada komponen Anda.
Tips men-debug
Untuk pengalaman penelusuran kesalahan yang lebih baik, unduh simbol penelusuran kesalahan dari server simbol Microsoft publik:
Untuk mengunduh simbol penelusuran kesalahan
Pada bilah menu, pilih Alat, Opsi.
Dalam kotak dialog Opsi , perluas Penelusuran Kesalahan dan pilih Simbol.
Pilih Microsoft Symbol Servers dan pilih tombol OK .
Mungkin perlu waktu untuk mengunduh simbol untuk pertama kalinya. Untuk performa yang lebih cepat saat berikutnya Anda menekan F5, tentukan direktori lokal untuk menyimpan simbol.
Saat Anda men-debug solusi JavaScript yang memiliki DLL komponen, Anda dapat mengatur debugger untuk mengaktifkan langkah melalui skrip atau melangkah melalui kode asli dalam komponen, tetapi tidak keduanya pada saat yang sama. Untuk mengubah pengaturan, buka menu pintasan untuk simpul proyek JavaScript di Penjelajah Solusi dan pilih Properti, Debugging, Jenis Debugger.
Pastikan untuk memilih kemampuan yang sesuai dalam perancang paket. Anda dapat membuka perancang paket dengan membuka file Package.appxmanifest. Misalnya, jika Anda mencoba mengakses file secara terprogram di folder Gambar, pastikan untuk memilih kotak centang Pustaka Gambar di panel Kemampuan perancang paket.
Jika kode JavaScript Anda tidak mengenali properti atau metode publik dalam komponen, pastikan bahwa di JavaScript Anda menggunakan casing unta. Misalnya, ComputeResult metode C++ harus dirujuk seperti computeResult dalam JavaScript.
Jika Anda menghapus proyek komponen C++ Windows Runtime dari solusi, Anda juga harus menghapus referensi proyek secara manual dari proyek JavaScript. Kegagalan untuk melakukannya mencegah operasi debug atau build berikutnya. Jika perlu, Anda kemudian dapat menambahkan referensi perakitan ke DLL.