Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
důležitá rozhraní API
Zjistěte, jak pracovat v samostatném vlákně odesláním pracovní položky do fondu vláken. Použijte to k udržování responzivního uživatelského rozhraní, zatímco dokončení práce trvá značné množství času, a použijte ho k paralelnímu dokončení více úloh.
Vytvoření a odeslání pracovní položky
Vytvořte pracovní položku voláním RunAsync. Zadejte delegáta k provedení práce (můžete použít lambda nebo funkci delegáta). Všimněte si, že RunAsync vrací objekt IAsyncAction ; uložte tento objekt pro použití v dalším kroku.
K dispozici jsou tři verze runAsync , takže můžete volitelně určit prioritu pracovní položky a určit, jestli běží souběžně s jinými pracovními položkami.
Následující příklad vytvoří pracovní položku a předá funkci lambda, která provede danou práci:
// The nth prime number to find.
const uint n = 9999;
// Receives the result.
ulong nthPrime = 0;
// Simulates work by searching for the nth prime number. Uses a
// naive algorithm and counts 2 as the first prime number.
// Capture the DispatcherQueue before entering the background lambda.
var dispatcherQueue = Microsoft.UI.Dispatching.DispatcherQueue.GetForCurrentThread();
IAsyncAction asyncAction = Windows.System.Threading.ThreadPool.RunAsync(
(workItem) =>
{
uint progress = 0; // For progress reporting.
uint primes = 0; // Number of primes found so far.
ulong i = 2; // Number iterator.
if ((n >= 0) && (n <= 2))
{
nthPrime = n;
return;
}
while (primes < (n - 1))
{
if (workItem.Status == AsyncStatus.Canceled)
{
break;
}
// Go to the next number.
i++;
// Check for prime.
bool prime = true;
for (uint j = 2; j < i; ++j)
{
if ((i % j) == 0)
{
prime = false;
break;
}
};
if (prime)
{
// Found another prime number.
primes++;
// Report progress at every 10 percent.
uint temp = progress;
progress = (uint)(10.0*primes/n);
if (progress != temp)
{
String updateString;
updateString = "Progress to " + n + "th prime: "
+ (10 * progress) + "%\n";
// Update the UI thread with the DispatcherQueue.
dispatcherQueue.TryEnqueue(
Microsoft.UI.Dispatching.DispatcherQueuePriority.High,
() => UpdateUI(updateString));
}
}
}
// Return the nth prime number.
nthPrime = i;
});
// A reference to the work item is cached so that we can trigger a
// cancellation when the user presses the Cancel button.
m_workItem = asyncAction;
// The nth prime number to find.
const unsigned int n{ 9999 };
// A shared pointer to the result.
// We use a shared pointer to keep the result alive until the
// work is done.
std::shared_ptr<unsigned long> nthPrime = std::make_shared<unsigned long>(0);
// Simulates work by searching for the nth prime number. Uses a
// naive algorithm and counts 2 as the first prime number.
// Capture the DispatcherQueue before entering the background lambda.
auto dispatcherQueue{ Microsoft::UI::Dispatching::DispatcherQueue::GetForCurrentThread() };
// A reference to the work item is cached so that we can trigger a
// cancellation when the user presses the Cancel button.
m_workItem = Windows::System::Threading::ThreadPool::RunAsync(
[=, strongThis = get_strong()](Windows::Foundation::IAsyncAction const& workItem)
{
unsigned int progress = 0; // For progress reporting.
unsigned int primes = 0; // Number of primes found so far.
unsigned long int i = 2; // Number iterator.
if ((n >= 0) && (n <= 2))
{
*nthPrime = n;
return;
}
while (primes < (n - 1))
{
if (workItem.Status() == Windows::Foundation::AsyncStatus::Canceled)
{
break;
}
// Go to the next number.
i++;
// Check for prime.
bool prime = true;
for (unsigned int j = 2; j < i; ++j)
{
if ((i % j) == 0)
{
prime = false;
break;
}
};
if (prime)
{
// Found another prime number.
primes++;
// Report progress at every 10 percent.
unsigned int temp = progress;
progress = static_cast<unsigned int>(10.f*primes / n);
if (progress != temp)
{
std::wstringstream updateStream;
updateStream << L"Progress to " << n << L"th prime: " << (10 * progress) << std::endl;
std::wstring updateString = updateStream.str();
// Update the UI thread with the DispatcherQueue.
dispatcherQueue.TryEnqueue(
Microsoft::UI::Dispatching::DispatcherQueuePriority::High,
[strongThis, updateString]()
{
strongThis->UpdateUI(updateString);
});
}
}
}
// Return the nth prime number.
*nthPrime = i;
});
// The nth prime number to find.
const unsigned int n = 9999;
// A shared pointer to the result.
// We use a shared pointer to keep the result alive until the
// work is done.
std::shared_ptr<unsigned long> nthPrime = std::make_shared<unsigned long>(0);
// Simulates work by searching for the nth prime number. Uses a
// naive algorithm and counts 2 as the first prime number.
auto workItem = ref new Windows::System::Threading::WorkItemHandler(
[this, n, nthPrime](IAsyncAction^ workItem)
{
unsigned int progress = 0; // For progress reporting.
unsigned int primes = 0; // Number of primes found so far.
unsigned long int i = 2; // Number iterator.
if ((n >= 0) && (n <= 2))
{
*nthPrime = n;
return;
}
while (primes < (n - 1))
{
if (workItem->Status == AsyncStatus::Canceled)
{
break;
}
// Go to the next number.
i++;
// Check for prime.
bool prime = true;
for (unsigned int j = 2; j < i; ++j)
{
if ((i % j) == 0)
{
prime = false;
break;
}
};
if (prime)
{
// Found another prime number.
primes++;
// Report progress at every 10 percent.
unsigned int temp = progress;
progress = static_cast<unsigned int>(10.f*primes / n);
if (progress != temp)
{
String^ updateString;
updateString = "Progress to " + n + "th prime: "
+ (10 * progress).ToString() + "%\n";
// Update the UI thread with the CoreDispatcher.
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
CoreDispatcherPriority::High,
ref new DispatchedHandler([this, updateString]()
{
UpdateUI(updateString);
}));
}
}
}
// Return the nth prime number.
*nthPrime = i;
});
auto asyncAction = ThreadPool::RunAsync(workItem);
// A reference to the work item is cached so that we can trigger a
// cancellation when the user presses the Cancel button.
m_workItem = asyncAction;
Po volání metody RunAsync je pracovní položka zařazena do fronty fondu vláken a spustí se, jakmile je k dispozici vlákno. Pracovní položky fondu vláken běží asynchronně a můžou běžet v libovolném pořadí, proto se ujistěte, že pracovní položky fungují nezávisle.
Všimněte si, že pracovní položka zkontroluje vlastnost IAsyncInfo.Status a ukončí, pokud je pracovní položka zrušena.
Zpracovat dokončení pracovní položky
Zadejte obslužnou rutinu dokončení nastavením IAsyncAction.Completed vlastnost pracovní položky. Poskytněte delegáta (můžete použít výraz lambda nebo funkci delegáta), který zpracuje dokončení pracovní položky. Například použijte DispatcherQueue.TryEnqueue pro přístup k vláknu uživatelského rozhraní a zobrazení výsledku.
Následující příklad aktualizuje uživatelské rozhraní s výsledkem pracovní položky odeslané v kroku 1:
asyncAction.Completed = new AsyncActionCompletedHandler(
(IAsyncAction asyncInfo, AsyncStatus asyncStatus) =>
{
if (asyncStatus == AsyncStatus.Canceled)
{
return;
}
String updateString;
updateString = "\n" + "The " + n + "th prime number is "
+ nthPrime + ".\n";
// Update the UI thread with the DispatcherQueue.
dispatcherQueue.TryEnqueue(
Microsoft.UI.Dispatching.DispatcherQueuePriority.High,
() => UpdateUI(updateString));
});
m_workItem.Completed(
[=, strongThis = get_strong()](Windows::Foundation::IAsyncAction const& asyncInfo, Windows::Foundation::AsyncStatus const& asyncStatus)
{
if (asyncStatus == Windows::Foundation::AsyncStatus::Canceled)
{
return;
}
std::wstringstream updateStream;
updateStream << std::endl << L"The " << n << L"th prime number is " << *nthPrime << std::endl;
std::wstring updateString = updateStream.str();
// Update the UI thread with the DispatcherQueue.
dispatcherQueue.TryEnqueue(
Microsoft::UI::Dispatching::DispatcherQueuePriority::High,
[strongThis, updateString]()
{
strongThis->UpdateUI(updateString);
});
});
Všimněte si, že obslužná rutina dokončení kontroluje, zda byla pracovní položka zrušena před odesláním aktualizace uživatelského rozhraní.
Shrnutí a další kroky
Více se můžete dozvědět z ukázek vláken v sadě Windows App SDK na GitHubu.
Příbuzná témata
Windows developer