Обратный вызов CreateTimerQueueTimer и состояние состязания

Одно из возможных решений - перенести экземпляр своего профиля и сохранить там свой профиль. Что я хочу сказать из вашего поста

 def post(self,request,*args,**kwargs):
        user=User.objects.get(username=request.user.username)
        print(user)
        form=ProfileForm(request.POST)
        if form.is_valid():
            // profile is valid now bring profile instance
            profile = Profile.objects.get(username=user)
            profile.first_name = form.cleaned_data['first_name']
            profile.save()
            messages.success(request,('Profile Edited succesfully'))
            return render(
                request,
                'editprofile.html',
                context={
                    'form':ProfileForm
                }
            )
5
задан Steve Folly 24 January 2009 в 23:18
поделиться

2 ответа

Понятие использования объектного указателя как параметр функции обратного вызова не плохо отдельно. Однако, очевидно, необходимо запустить разрушение после того, как последний обратный вызов вышел.

Так, я не сделал бы краткий обзор Таймера и произошел бы из него вообще. Я использовал бы другой абстрактный класс TimerImpl и сделайте Timer использование класса a TimerImpl экземпляр:

class Timer
{
  TimerInstance* impl;
  void TimeOut() { impl->TimeOut(); }
public:
  ~Timer() {
    ... make sure the timer has ended and wont fire again after this line...
    delete impl;
  }
}

struct TimerImpl
{
  virtual void TimeOut()=0;
  virtual ~TimerImpl();
}

Таким образом, можно удостовериться, что разрушение не начнется до окончания Вас, говорят.

Вторая вещь, необходимо ожидать последнего события таймера для сжигания. Согласно документу MSDN, можно сделать это путем вызова

DeleteTimerQueueTimer(TimerQueue, Timer, INVALID_HANDLE_VALUE)
3
ответ дан 14 December 2019 в 19:28
поделиться

Вы почти наверняка не можете сделать этого с моделью наследования. Основная проблема состоит в том, что к тому времени, когда конструктор базового класса был введен, производный объект уже недопустим, но таймер мог бы стрелять, и ничто не останавливает его, делая попытку вызова виртуальной функции, который теперь приведет к неопределенному поведению.

Я думаю, что способом сделать это является обертка как это. Точка должна гарантировать, что нет никакого состояния состязания с попыткой диспетчеризировать 'приведенное к таймауту' событие.

Эта реализация все еще имеет один дефект. Существует шанс, событие таймера ожидает, когда объект - таймер начинает удаляться. Для деструктора возможно выпустить взаимное исключение и затем уничтожить взаимное исключение, в то время как поток таймера ожидает на взаимном исключении. Мы предотвратили гонку в отправке 'приведенного к таймауту' события, но поведение потока, ожидающего на взаимном исключении, которое уничтожается, зависит от реализации взаимного исключения.

static void callback( PVOID param, BOOLEAN timerOrWaitFired );

class TimerWrapper
{
    public:

        /* Take reference to std::auto_ptr to ensure ownership transfer is explicit */
        TimerWrapper( std::auto_ptr<Timer>& timer ) : timer_(timer)
        {
            ::CreateTimerQueueTimer( &htimer_, ..., callback, this, ... );
        }

        void TimedOut()
        {
            ScopedGuard guard( mutex_ );
            if( timer_.get() )
                timer_->TimedOut();
        }

        ~TimerWrapper()
        {
            ::DeleteTimerQueueTimer( htimer_, ... );
            ScopedGuard guard( mutex_ );
            timer_.reset();
        }

    private:

        Mutex mutex_;
        std::auto_ptr<Timer> timer_;
        HANDLE htimer_;
};

static void callback( PVOID param, BOOLEAN timerOrWaitFired )
{
    TimerWrapper* timer = reinterpret_cast< TimerWrapper* >( param );
    timer->TimedOut();
}
0
ответ дан 14 December 2019 в 19:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: