Aracılığıyla paylaş


Nasıl yapılır: bir gecikmeden sonra tamamlar bir görev oluşturma

Bu örnek, nasıl kullanacağınızı gösterir concurrency::task, concurrency::cancellation_token_source, concurrency::cancellation_token, concurrency::task_completion_event, concurrency::timer, ve concurrency::call bir gecikmeden sonra tamamlar bir görev oluşturmak için sınıflar.Bazen verileri yoklamak, zaman aşımları tanıtmak, kullanıcı girişini işleme önceden belirlenmiş bir süre için gecikme ve benzeri döngüleri oluşturmak için bu yöntemi kullanın.

Örnek

Aşağıdaki örnekte gösterildiği complete_after ve cancel_after_timeout işlevleri.complete_after İşlev oluşturur bir task nesne belirtilen gecikmeden sonra tamamlar.Kullandığı bir timer nesnesi ve bir call ayarlamak için nesne bir task_completion_event belirtilen gecikmeden sonra nesne.Kullanarak task_completion_event sınıfı, bir görev tamamlandıktan sonra bir iş parçacığı tanımlayabilirsiniz veya başka bir görev bir değer kullanılabilir durumda olduğunu bildirir.Olay ayarladığınızda, dinleyici görevleri tamamlamak ve bunların devamlılığını çalışacak şekilde zamanlanır.

İpucuİpucu

Hakkında daha fazla bilgi için timer ve call zaman uyumsuz aracılar kitaplığı parçası olan sınıfları Bkz: Zaman uyumsuz ileti blokları.

cancel_after_timeout İşlev yapıları yönetebilen, complete_after bu görevi belirli bir süre önce tamamlanmazsa bir görevi iptal etmek için işlev.cancel_after_timeout İşlevi iki görev oluşturur.İlk görev başarılı olduğunu gösterir ve sağlanan görev tamamlandıktan sonra tamamlar; İkinci görev başarısız olduğunu gösterir ve sonra belirtilen zaman aşımı tamamlar.cancel_after_timeout İşlev başarı veya başarısızlık görev tamamlandığında çalışacak bir devamı görev oluşturur.İlk hata görev gerçekleştirdiğinde, devamı belirteç kaynağı genel görevi iptal etmek için iptal eder.

// Creates a task that completes after the specified delay.
task<void> complete_after(unsigned int timeout)
{
    // A task completion event that is set when a timer fires.
    task_completion_event<void> tce;

    // Create a non-repeating timer.
    auto fire_once = new timer<int>(timeout, 0, nullptr, false);
    // Create a call object that sets the completion event after the timer fires.
    auto callback = new call<int>([tce](int)
    {
        tce.set();
    });

    // Connect the timer to the callback and start the timer.
    fire_once->link_target(callback);
    fire_once->start();

    // Create a task that completes after the completion event is set.
    task<void> event_set(tce);

    // Create a continuation task that cleans up resources and
    // and return that continuation task.
    return event_set.then([callback, fire_once]()
    {
        delete callback;
        delete fire_once;
    });
}

// Cancels the provided task after the specifed delay, if the task
// did not complete.
template<typename T>
task<T> cancel_after_timeout(task<T> t, cancellation_token_source cts, unsigned int timeout)
{
    // Create a task that returns true after the specified task completes.
    task<bool> success_task = t.then([](T)
    {
        return true;
    });
    // Create a task that returns false after the specified timeout.
    task<bool> failure_task = complete_after(timeout).then([]
    {
        return false;
    });

    // Create a continuation task that cancels the overall task 
    // if the timeout task finishes first.
    return (failure_task || success_task).then([t, cts](bool success)
    {
        if(!success)
        {
            // Set the cancellation token. The task that is passed as the
            // t parameter should respond to the cancellation and stop
            // as soon as it can.
            cts.cancel();
        }

        // Return the original task.
        return t;
    });
}

Aşağıdaki örnek hesaplar [0, 100000] aralıktaki asal sayıların sayısı birden çok kez.Belirli bir süre içinde tamamlanamazsa işlem başarısız olur.count_primes İşlevinin nasıl kullanılacağını gösterir cancel_after_timeout işlev.Bu primes verilen aralıktaki sayar ve görev verilen sürede tamamlanmaz başarısız olur.wmain İşlev çağrıları count_primes işlevini birden çok kez.Her zaman, zaman sınırı tahtasını.Programın geçerli süre içinde işlemi tamamlanmıyor sonra tamamlanır.

// Determines whether the input value is prime.
bool is_prime(int n)
{
    if (n < 2)
        return false;
    for (int i = 2; i < n; ++i)
    {
        if ((n % i) == 0)
            return false;
    }
    return true;
}

// Counts the number of primes in the range [0, max_value].
// The operation fails if it exceeds the specified timeout.
bool count_primes(unsigned int max_value, unsigned int timeout)
{
    cancellation_token_source cts;

    // Create a task that computes the count of prime numbers.
    // The task is canceled after the specified timeout.
    auto t = cancel_after_timeout(task<size_t>([max_value, timeout]
    {
        combinable<size_t> counts;
        parallel_for<unsigned int>(0, max_value + 1, [&counts](unsigned int n) 
        {
            // Respond if the overall task is cancelled by canceling 
            // the current task.
            if (is_task_cancellation_requested())
            {
                cancel_current_task();
            }
            // NOTE: You can replace the calls to is_task_cancellation_requested
            // and cancel_current_task with a call to interruption_point.
            // interruption_point();

            // Increment the local counter if the value is prime.
            if (is_prime(n))
            {
                counts.local()++;
            }
        });
        // Return the sum of counts across all threads.
        return counts.combine(plus<size_t>());
    }, cts.get_token()), cts, timeout);

    // Print the result.
    try
    {
        auto primes = t.get();
        wcout << L"Found " << primes << L" prime numbers within " 
              << timeout << L" ms." << endl;
        return true;
    }
    catch (const task_canceled& e)
    {
        wcout << L"The task timed out." << endl;
        return false;
    }
}

int wmain()
{
    // Compute the count of prime numbers in the range [0, 100000] 
    // until the operation fails.
    // Each time the test succeeds, the time limit is halved.

    unsigned int max = 100000;
    unsigned int timeout = 5000;

    bool success = true;
    do
    {
        success = count_primes(max, timeout);
        timeout /= 2;
    } while (success);
}
/* Sample output:
    Found 9592 prime numbers within 5000 ms.
    Found 9592 prime numbers within 2500 ms.
    Found 9592 prime numbers within 1250 ms.
    Found 9592 prime numbers within 625 ms.
    The task timed out.
*/

Genel görev iptal edildikten sonra bir gecikmeden sonra görevleri iptal etmek için bu tekniği kullandığınızda, herhangi bir başlamamış görevler başlatılmaz.Ancak, herhangi bir uzun süredir çalışan görevleri iptali için zamanında yanıt vermek önemlidir.Bu örnekte, count_primes yöntem çağrıları concurrency::is_task_cancellation_requested ve cancel_current_task iptali için yanıt vermek için işlevler.(Alternatif olarak, arama concurrency::interruption_point işlevi).Görev iptali hakkında daha fazla bilgi için bkz: ppl iptali.

Bu örnek için tam kod aşağıdadır:

// task-delay.cpp
// compile with: /EHsc
#include <ppltasks.h>
#include <agents.h>
#include <iostream>

using namespace concurrency;
using namespace std;

// Creates a task that completes after the specified delay.
task<void> complete_after(unsigned int timeout)
{
    // A task completion event that is set when a timer fires.
    task_completion_event<void> tce;

    // Create a non-repeating timer.
    auto fire_once = new timer<int>(timeout, 0, nullptr, false);
    // Create a call object that sets the completion event after the timer fires.
    auto callback = new call<int>([tce](int)
    {
        tce.set();
    });

    // Connect the timer to the callback and start the timer.
    fire_once->link_target(callback);
    fire_once->start();

    // Create a task that completes after the completion event is set.
    task<void> event_set(tce);

    // Create a continuation task that cleans up resources and
    // and return that continuation task.
    return event_set.then([callback, fire_once]()
    {
        delete callback;
        delete fire_once;
    });
}

// Cancels the provided task after the specifed delay, if the task
// did not complete.
template<typename T>
task<T> cancel_after_timeout(task<T> t, cancellation_token_source cts, unsigned int timeout)
{
    // Create a task that returns true after the specified task completes.
    task<bool> success_task = t.then([](T)
    {
        return true;
    });
    // Create a task that returns false after the specified timeout.
    task<bool> failure_task = complete_after(timeout).then([]
    {
        return false;
    });

    // Create a continuation task that cancels the overall task 
    // if the timeout task finishes first.
    return (failure_task || success_task).then([t, cts](bool success)
    {
        if(!success)
        {
            // Set the cancellation token. The task that is passed as the
            // t parameter should respond to the cancellation and stop
            // as soon as it can.
            cts.cancel();
        }

        // Return the original task.
        return t;
    });
}

// Determines whether the input value is prime.
bool is_prime(int n)
{
    if (n < 2)
        return false;
    for (int i = 2; i < n; ++i)
    {
        if ((n % i) == 0)
            return false;
    }
    return true;
}

// Counts the number of primes in the range [0, max_value].
// The operation fails if it exceeds the specified timeout.
bool count_primes(unsigned int max_value, unsigned int timeout)
{
    cancellation_token_source cts;

    // Create a task that computes the count of prime numbers.
    // The task is canceled after the specified timeout.
    auto t = cancel_after_timeout(task<size_t>([max_value, timeout]
    {
        combinable<size_t> counts;
        parallel_for<unsigned int>(0, max_value + 1, [&counts](unsigned int n) 
        {
            // Respond if the overall task is cancelled by canceling 
            // the current task.
            if (is_task_cancellation_requested())
            {
                cancel_current_task();
            }
            // NOTE: You can replace the calls to is_task_cancellation_requested
            // and cancel_current_task with a call to interruption_point.
            // interruption_point();

            // Increment the local counter if the value is prime.
            if (is_prime(n))
            {
                counts.local()++;
            }
        });
        // Return the sum of counts across all threads.
        return counts.combine(plus<size_t>());
    }, cts.get_token()), cts, timeout);

    // Print the result.
    try
    {
        auto primes = t.get();
        wcout << L"Found " << primes << L" prime numbers within " 
              << timeout << L" ms." << endl;
        return true;
    }
    catch (const task_canceled& e)
    {
        wcout << L"The task timed out." << endl;
        return false;
    }
}

int wmain()
{
    // Compute the count of prime numbers in the range [0, 100000] 
    // until the operation fails.
    // Each time the test succeeds, the time limit is halved.

    unsigned int max = 100000;
    unsigned int timeout = 5000;

    bool success = true;
    do
    {
        success = count_primes(max, timeout);
        timeout /= 2;
    } while (success);
}
/* Sample output:
    Found 9592 prime numbers within 5000 ms.
    Found 9592 prime numbers within 2500 ms.
    Found 9592 prime numbers within 1250 ms.
    Found 9592 prime numbers within 625 ms.
    The task timed out.
*/

Kod Derleniyor

Kodu derlemek için kopyalayabilir ve sonra Visual Studio projesinde yapıştırın veya adlı bir dosyaya yapıştırın görev delay.cpp ve ardından Visual Studio komut istemi penceresinde aşağıdaki komutu çalıştırın.

cl.exe /EHsc task-delay.cpp

Ayrıca bkz.

Başvuru

Sınıf (eşzamanlılık Runtime) görev

cancellation_token_source sınıfı

cancellation_token sınıfı

task_completion_event sınıfı

is_task_cancellation_requested işlevi

cancel_current_task işlevi

interruption_point işlevi

Timer sınıfı

Çağrı sınıfı

Kavramlar

Görev paralellik (eşzamanlılık çalışma zamanı)

Zaman uyumsuz ileti blokları

ppl iptali