Task

Windows10 で Task を使います。

前田稔の超初心者のプログラム入門

プログラムの説明

  1. Windows10 の Task Programing は Win32 API とは少し勝手が違うようです。
    Win32 の Task Programing は「超初心者のプログラム入門(C/C++)/Task を起動」を参照して下さい。
    Windows10(Store App) & Visual Studio Community 2015 の環境で作成します。
    環境が違うと動かないことがあるので留意して下さい。
  2. Visual Studio Community 2015 を起動します。
    [ファイル][新規作成][プロジェクト][Visual C++][Windows]から[空白アプリ(ユニバーサル Windows)]を選びます。
    App1(規定値)でプロジェクトを生成します。
    そのままコンパイル&実行すると、空のウインドウが表示されます。
  3. MainPage.xaml.cpp を修正します。
    #include "pch.h"
    #include "MainPage.xaml.h"
    
    using namespace App1;
    
    using namespace Platform;
    using namespace Windows::Foundation;
    using namespace Windows::Foundation::Collections;
    using namespace Windows::UI::Xaml;
    using namespace Windows::UI::Xaml::Controls;
    using namespace Windows::UI::Xaml::Controls::Primitives;
    using namespace Windows::UI::Xaml::Data;
    using namespace Windows::UI::Xaml::Input;
    using namespace Windows::UI::Xaml::Media;
    using namespace Windows::UI::Xaml::Navigation;
    using namespace concurrency;
    using namespace std;
    
    // 空白ページのアイテム テンプレートについては、http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 を参照してください
    task<void> Time(int rnd, wstring id)
    {
        return create_task([rnd, id]
        {
            Windows::Globalization::Calendar^ cal;
            int ss, ns;
            wchar_t str[40];
            for (int i = 0; i < 3; i++)
            {
                cal = ref new Windows::Globalization::Calendar();
                ss = cal->Second;
                ns = cal->Nanosecond;
                swprintf(str, 40, L"%s : Time %d:%d\n", id.data(), ss, ns);
                OutputDebugString(str);
                Sleep(rand() % rnd);
            }
        });
    }
    
    MainPage::MainPage()
    {
        InitializeComponent();
        auto t = Time(1000, L"A");
        t.then([this]() {
            OutputDebugString(L"END Task\n");
        });
    }
    
  4. MainPage() から Task で定義した Time() 関数に 1000 と L"A" を渡します。
    t.then([this]() でタスクの終了を待って L"END Task\n" を印字します。
  5. Time(int rnd, wstring id) でパラメータを受け取ります。
    rnd(1000) は Sleep() 間隔を調整するための値です。
    id(L"A") は Task を識別するIDです。
    return create_task([rnd, id] で Task を設定します。
    Task では rnd を使って間隔を取りながらタイムスタンプを3回印字します。
    ss が秒の値で ns がナノセコンドの値です。
    ss と ns を編集して OutputDebugString(); で出力ウインドウに印字します。
  6. t.then([this]() { OutputDebugString(L"END Task\n"); }); でタスクの終了を確認します。

同時に起動

  1. パラメータを変えて、二個の Task を同時に起動します。
    MainPage() を次のように修正して下さい。
    MainPage::MainPage()
    {
        InitializeComponent();
        auto t = Time(500, L"A");
        auto t2 = Time(100, L"B");
        (t && t2).then([this]() {
            OutputDebugString(L"END Task\n");
        });
    }
    
  2. Time 関数に Sleep() 間隔を調整する rnd と識別する id を渡して、二回 Task を起動します。
    auto t2 = Time(100, L"B"); は後から起動されますが rnd が 100 なので先に印字が終わります。
    (t && t2).then([this]() { ・・・ } でタスクを起動して終了を待ちます。
    終了すると L"END Task\n" を印字します。
    A と B が同時に実行され OutputDebugString() の実行順に印字されるので確認して下さい。
  3. システムからのメッセージが途中に沢山印字されますが、実行結果は次のようになりました。
    A : Time 46:592793500
    B : Time 46:592792200
    A : Time 46:640237400
    B : Time 46:640236600
    B : Time 46:709434500
    A : Time 47:108141700
    END Task
    
  4. Task を起動 ではタイムスタンプをミリ秒で取得して印字します。
    MessageDialog では Task で MessageDialog の終了を待ち合わせます。
    install Folder Read では Task でファイルの入力を待ち合わせます。
    Local Folder では Task でファイルの出力を待ち合わせます。
    Picker Image では Task で Image の入力を待ち合わせます。

超初心者のプログラム入門(C/C++)