#include "pch.h" #include "Class1.h" #include #include using namespace concurrency; using namespace Platform::Collections; using namespace Windows::Foundation::Collections; using namespace Windows::Foundation; using namespace Windows::UI::Core; using namespace UwpTestWinRtComponentCpp; using namespace Platform; Class1::Class1() { } //Public API IVector^ 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 logs(6, numbers); // See http://msdn.microsoft.com/en-us/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(); int len = safe_cast(logs.extent.size()); for (int i = 0; i < len; i++) { res->Append(logs[i]); } // res is implicitly cast to IVector return res; } // 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^, double>^ Class1::GetPrimesOrdered(int first, int last) { return create_async([this, first, last] (progress_reporter reporter) -> IVector^ { // Ensure that the input values are in range. if (first < 0 || last < 0) { throw ref new InvalidArgumentException(); } // Perform the computation in parallel. concurrent_vector 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()); 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(primes.begin(), primes.end()); }); } // 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^ 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 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 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); }); }