# Please add AsyncQuitRetrier class to JUCE

**URL:** <https://forum.juce.com/t/please-add-asyncquitretrier-class-to-juce/21393>\
**Category:** General JUCE discussion\
**Created:** [March 18, 2017, 2:35am UTC](https://forum.juce.com/t/please-add-asyncquitretrier-class-to-juce/21393 "2017-03-18T02:35:05Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![railjonrogut](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/railjonrogut/32/505_2.png) [@railjonrogut](https://forum.juce.com/u/railjonrogut)\
**Post date:** [March 18, 2017, 2:35am UTC](https://forum.juce.com/t/please-add-asyncquitretrier-class-to-juce/21393/1 "2017-03-18T02:35:05Z")

</div>

If you Quit while a FileChooser is open it causes a crash. I see that you get around this in ProJucer using an AsyncQuitRetrier class.

```auto
struct AsyncQuitRetrier : private Timer
{
    AsyncQuitRetrier() { startTimer (500); }

    void timerCallback() override
    {
        stopTimer();
        delete this;

        if (JUCEApplicationBase* app = JUCEApplicationBase::getInstance())
            app->systemRequestedQuit();
    }

    JUCE_DECLARE_NON_COPYABLE (AsyncQuitRetrier)
};

void ProjucerApplication::systemRequestedQuit()
{
    if (server != nullptr)
    {
        sendQuitMessageToIDE (server);
    }
    else if (ModalComponentManager::getInstance()->cancelAllModalComponents())
    {
        new AsyncQuitRetrier();
    }
    else
    {
        if (closeAllMainWindows())
            quit();
    }
}
```

Perhaps you can add this to the JUCE Demo as well.

Thanks,

Rail

---

<div class="post-metadata">

**Author:** ![railjonrogut](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/railjonrogut/32/505_2.png) [@railjonrogut](https://forum.juce.com/u/railjonrogut)\
**Post date:** [March 18, 2017, 2:40am UTC](https://forum.juce.com/t/please-add-asyncquitretrier-class-to-juce/21393/2 "2017-03-18T02:40:13Z")

</div>

… or better yet… add the AsyncQuitRetrier class to the JUCE code and in a ProJucer created GUI app in systemRequestedQuit() add the relevant code automatically:

```
void systemRequestedQuit() override
{
    // This is called when the app is being asked to quit: you can ignore this
    // request and let the app carry on running, or call quit() to allow the app to close.

    if (ModalComponentManager::getInstance()->cancelAllModalComponents())
        new AsyncQuitRetrier();
    else
        quit();
}

```

Rail

---

<div class="post-metadata">

**Author:** ![railjonrogut](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/railjonrogut/32/505_2.png) [@railjonrogut](https://forum.juce.com/u/railjonrogut)\
**Post date:** [March 18, 2017, 9:48am UTC](https://forum.juce.com/t/please-add-asyncquitretrier-class-to-juce/21393/3 "2017-03-18T09:48:14Z")

</div>

Seems like the perfect place to use the new Timer:: callAfterDelay()

In JUCEApplication:

```
 #if JUCE_COMPILER_SUPPORTS_LAMBDAS

struct AsyncQuitRetrier
{
    AsyncQuitRetrier()
    {
        Timer::callAfterDelay (500, std::bind (&AsyncQuitRetrier::lambdaTimerCallback, this));
    }
    
    void lambdaTimerCallback()
    {
        if (JUCEApplicationBase* app = JUCEApplicationBase::getInstance())
            app->systemRequestedQuit();
    }
    
    JUCE_DECLARE_NON_COPYABLE (AsyncQuitRetrier)
};

#else

struct AsyncQuitRetrier : private Timer
{
    AsyncQuitRetrier() { startTimer (500); }

    void timerCallback() override
    {
        stopTimer();
        delete this;
        
        if (JUCEApplicationBase* app = JUCEApplicationBase::getInstance())
            app->systemRequestedQuit();
    }

    JUCE_DECLARE_NON_COPYABLE (AsyncQuitRetrier)
};

#endif

```

Rail

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://forum.juce.com/u/jules)\
**Post date:** [March 22, 2017, 12:10pm UTC](https://forum.juce.com/t/please-add-asyncquitretrier-class-to-juce/21393/4 "2017-03-22T12:10:45Z")

</div>

TBH with the new Timer::callAfterDelay, there’s not really much point in us adding a class to the library, because it becomes trivial to write:

```
Timer::callAfterDelay (500, []()
{
    if (auto app = JUCEApplicationBase::getInstance()
        app->systemRequestedQuit(); 
});

```
