Tengo una aplicación donde tengo QOBJects que contienen todos un QNetworkAccessManager. Soy consciente de que se sugiere que solo lo tenga en cada aplicación, pero como estoy haciendo más de 6 llamadas al mismo tiempo, necesitaba tenerlo así. Entonces, así es como comienzo los hilos.El número de subprocesos aumenta mucho, incluso al eliminar los hilos
FileUploader *fileUploader = new FileUploader(_fileList);
QThread *fileUploaderThread = new QThread();
fileUploader->moveToThread(fileUploaderThread);
// uploader > model
connect(fileUploader, SIGNAL(progressChangedAt(int)), _model, SLOT(reportProgressChanged(int)), Qt::QueuedConnection);
connect(fileUploader, SIGNAL(statusChangedAt(int)), _model, SLOT(reportStatusChanged(int)), Qt::QueuedConnection);
// uploader > its thread
connect(fileUploader, SIGNAL(canceled()), fileUploaderThread, SLOT(quit()), Qt::QueuedConnection);
connect(fileUploader, SIGNAL(finished()), fileUploaderThread, SLOT(quit()), Qt::QueuedConnection);
// uploader > this
connect(fileUploader, SIGNAL(canceled()), this, SLOT(deleteFinishedUploader()), Qt::QueuedConnection);
connect(fileUploader, SIGNAL(finished()), this, SLOT(deleteFinishedUploader()), Qt::QueuedConnection);
connect(fileUploader, SIGNAL(finishedCurrentUpload()), this, SLOT(uploadNextFileOrFinish()), Qt::QueuedConnection);
// thread > this
connect(fileUploaderThread, SIGNAL(finished()), this, SLOT(checkIfAllThreadsAreFinished()), Qt::QueuedConnection);
connect(fileUploaderThread, SIGNAL(finished()), this, SLOT(deleteFinishedThread()), Qt::QueuedConnection);
// this > uploader
connect(this, SIGNAL(cancel()), fileUploader, SLOT(cancel()), Qt::QueuedConnection);
fileUploaderThread->start();
QMetaObject::invokeMethod(fileUploader, "init", Qt::QueuedConnection);
QMetaObject::invokeMethod(fileUploader, "uploadAt", Qt::QueuedConnection, Q_ARG(int, startIndex));
QMutexLocker locker(&_mutex);
_threadCount++;
Cada tema se inicia con un índice a una lista para que puedan ir a buscar lo que necesitan para cargar y continuar unos 5 pasos (llamadas con el QNetworkAccessManager). Cuando no hay más elementos a cargar, las señales FileUploader "acabado()" que llama a la deleteFinishedThread
y deleteFinishedUploader
donde hago:
QThread *thread = qobject_cast<QThread*>(sender());
if(thread != NULL) thread->deleteLater();
o
FileUploader *fileUploader = qobject_cast<FileUploader*>(sender());
if(fileUploader != NULL) fileUploader->deleteLater();
Estos se supone que debe eliminar los hilos cuando están hechos.
El problema es que cada vez que comienzo (por ejemplo) 3 subprocesos que tienen 1 archivo para cargar y manejar cada uno, el conteo de subprocesos aumenta en 8-10. Esto significa que el recuento de subprocesos va de aproximadamente 5 a 100 si reinicio el proceso de carga varias veces.
¿Qué estoy haciendo mal? ¿O es mi mayor problema que use el "Administrador de tareas de Windows" para controlar esto? Estoy manejando todas las respuestas del QNAM que elimino y todo parece borrarse, pero aún me estoy rascando cuando el conteo de hilos sigue aumentando ...
EDIT: En mi fileuploader creo un objeto (Administrador) en el montón que tiene un QNetworkAccessManager en la pila. Cuando el fileuploader se elimina, se llama a "deleteLater()" en el Administrador, pero nunca se elimina. Intentamos eliminar el Administrador y establecerlo en NULO, pero eso nos dio una infracción de acceso ya que el Administrador aún no había finalizado (el QNetwork.dll informó el problema, por lo que debe ser algo dentro del QNAM que todavía se esté ejecutando). Los momentos en los que no obtuvimos una infracción de acceso, el objeto se eliminó y el recuento de subprocesos volvió a la normalidad. ¿Qué puede vivir dentro de QNAM y evitar que lo elimine cuando se sale del alcance? ¿Debo crear el QNAM en el montón? En esta etapa no de los destructores están siendo llamados, incluso cuando se llama a deleteLater() ...
Además, ¿cómo puedo reducir el mango cuenta?
agregó una recompensa. su pregunta necesita un poco de amor ... – UmNyobe
oh muchas gracias. Hiciste mi día :) – chikuba
un comentario: si todavía los usas, llama a 'QMetaObject :: invokeMethod (' antes de iniciar 'fileUploaderThread'. Es la mejor manera de asegurarte de que estas ranuras se llamen primero cuando se inicie el ciclo de subprocesos. – UmNyobe