Creé una aplicación de Visual Studio 2019, con OutputPanes, una se usa para ver los registros de seguimiento de WorkerThread.

En WorkerThread, lleno un CStringList mStrDebugList si ha sucedido algo útil, e informo a la IU principal con PostMessage para leer y mostrar ahora.

//////////////////////////////////////////////////////////////////////////
//  TRACE Debug messsages for this App wide 
void TRACE_DEBUG(LPCTSTR pszstring)
{
    TRACE(pszstring);

    CTestApp* pApp = (CTestApp*)AfxGetApp();
    if (pApp)
    {
        TAutoLock lock(res);
        theApp.mStrDebugList.AddTail(pszstring);
    }

Esto funciona, pero si la aplicación está minimizada o no en primer plano, después de horas, CStringList contiene demasiados elementos (> 20k) y la IU principal no responde (~ 5Min) hasta que todos los elementos se leen y eliminan en el UI.

void COutputWnd::FillInfoWindow()
{
    TestApp* pApp = (CTestApp*)AfxGetApp();
    if (pApp)
    {
        TAutoLock lock(res);

        CString str;
        while (!theApp.mStrDebugList.IsEmpty ())
        {
            str.Format(_T("%5d %s"),nCounter, theApp.mStrDebugList.GetHead ());     
            m_wndOutputDebug.AddString (str);
            theApp.mStrDebugList.RemoveHead ();
        }

        // Scroll to the end of Listbox
        int nCount = m_wndOutputDebug.GetCount();
        m_wndOutputDebug.SetTopIndex(nCount-1);
    }
}

Mi pregunta es, ¿cómo puedo verificar dentro de WorkerThread si la interfaz de usuario no está activa (inactiva), para evitar llenar el CStringList con demasiados elementos?

0
Tom Tom 21 ene. 2021 a las 18:03

1 respuesta

La mejor respuesta

Creo que tu enfoque es incorrecto. ¿Qué hará si el hilo de la interfaz de usuario (principal) está "inactivo"? ¿Evitar que el hilo de trabajo funcione, es decir, suspenderlo? ¿Dejará de recopilar datos? ¿Y qué pasará cuando la interfaz de usuario vuelva a estar en primer plano? El hilo de trabajo tendrá que recopilar TODOS los datos, que aún deberán agregarse a la ventana de depuración, todos a la vez, por lo que el tiempo de respuesta total será aún mayor.

Si está agregando los datos a la ventana de depuración (supongo que una clase derivada de listbox) que lleva tanto tiempo, no hay una solución real, deben agregarse de todos modos. Solo algunas optimizaciones:

  • Llame a m_wndOutputDebug.SetRedraw(FALSE); antes de agregar las cadenas y m_wndOutputDebug.SetRedraw(TRUE); y m_wndOutputDebug.Invalidate(); cuando haya terminado, tal vez la demora se deba a que la interfaz de usuario intenta dibujar la ventana de depuración inmediatamente después de agregar cada elemento.
  • Evite esas llamadas a GetHead()/RemoveHead() para navegar por la lista (es sobrecarga, ya que puede reorganizar / reasignar la lista), en su lugar llame a RemoveAll() cuando haya terminado, no hay problema con esto porque bloquea la operación.

Una nota al margen (no relacionada con el rendimiento), ¿por qué necesita llamar a AfxGetApp()? De todos modos, no estás haciendo nada con él (pApp). Y tienes el singleton theApp disponible (AfxGetApp() debería devolver la dirección de theApp, ¿no?).

1
Constantine Georgiou 21 ene. 2021 a las 20:48