Таймер обратного вызова oneshot, используемый C ++ 11 std :: async - PullRequest
0 голосов
/ 24 сентября 2019

Я создал его с помощью std :: async в C ++ 11. Что-то не так с ним?Я хотел бы получить отзыв о том, что я могу улучшить или что не так.

У меня нет опыта работы с C ++ 11, поэтому мне интересно, является ли использование асинхронного или умного указателя неправильным.Есть ли проблема без вызова get () для возвращаемого значения асинхронного std :: future?

Спасибо!

HEADER (Timer.h)

#pragma once
#include <chrono>
#include <functional>
#include <map>
#include <future>

enum class TIMER_STATUS
{
    RUNNING,
    FINISHED,
    CANCELED,
};
struct TIMER_HANDLE_T
{
    friend class Timer;

public:
TIMER_HANDLE_T();
~TIMER_HANDLE_T();

private:
    std::chrono::microseconds afterMS;  
    std::function<void(void)> callback; 
    std::future<void> waiter;   
    std::promise<void> exitSignal;  //used by cancel    
    TIMER_STATUS status;
};
typedef std::shared_ptr<TIMER_HANDLE_T> TIMER_HANDLE;

class Timer
{

public:
    Timer();
    ~Timer();

    //Start
    TIMER_HANDLE Set(std::chrono::milliseconds ms, std::function<void(void)> callback);
    //Cancel
    bool Reset(TIMER_HANDLE h);
    TIMER_STATUS GetStatus(TIMER_HANDLE h);

private:
    void Wait(TIMER_HANDLE h, std::future<void> exitSig);
};

CPP (Timer.cpp)

#include "Timer.h"
#include <thread>

TIMER_HANDLE_T::TIMER_HANDLE_T(){   }
TIMER_HANDLE_T::~TIMER_HANDLE_T(){  }
Timer::Timer(){ }
Timer::~Timer(){    }

TIMER_HANDLE Timer::Set(std::chrono::milliseconds ms, std::function<void(void)> callback)
{
    std::shared_ptr<TIMER_HANDLE_T> th = std::make_shared<TIMER_HANDLE_T>();
    th->callback = callback;
    th->afterMS = ms;
    th->exitSignal = std::promise<void>();
    th->waiter = std::async(std::launch::async, &Timer::Wait, this, th, th->exitSignal.get_future());
    th->status = TIMER_STATUS::RUNNING;
    return std::move(th);
}
bool Timer::Reset(TIMER_HANDLE h)
{
    h->exitSignal.set_value();
    if (h->waiter.wait_for(std::chrono::milliseconds(1000)) == std::future_status::ready)
        return true;
    else
        return false;
}
TIMER_STATUS Timer::GetStatus(TIMER_HANDLE h)
{
    return h->status;
}

void Timer::Wait(TIMER_HANDLE h, std::future<void> exitSig)
{
    if (exitSig.wait_for(h->afterMS) == std::future_status::timeout)
    {
        h->callback();
        h->status = TIMER_STATUS::FINISHED;
    }
    else
    {
        h->status = TIMER_STATUS::CANCELED;
    }
}

USED (main.cpp)

#include "Timer.h"
#include <iostream>

std::chrono::system_clock::time_point start = std::chrono::system_clock::now();

void Callback()
{
    std::chrono::duration<double> sec = std::chrono::system_clock::now() - start;
    std::cout << "Callback - " << sec.count() << std::endl;

    //Do Something
}

int main()
{
    Timer t;
    TIMER_HANDLE b = t.Set(std::chrono::milliseconds(5000), &Callback);

std::this_thread::sleep_for(std::chrono::milliseconds(10000));

    return 0;
}

Вывод «Обратный вызов - 5.00091»

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...