Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Native Development

Reply
Developer
Posts: 134
Registered: ‎04-12-2013
My Device: BB Z10
My Carrier: Telenor

Issue with QtConcurrent for multithreading

Hi,

I am facing an issue with QtConcurrent. In my app I have to create a database first with 4 tables. These tables will be updated with the values I get from JSON reponses. So, I send the first JSON request first in one thread and waits for it to get finished.  But, now the first thread never gets finished. I never get a response to my request.

 

My code is below. home.cpp

Home::Home(bb::cascades::Application *app) :
		QObject(app) {
	bb::data::DataSource::registerQmlTypes();
	qmlRegisterType<CustomSqlDataSource>("com.du.data", 1, 0,
			"CustomSqlDataSource");

	Initialise(); //create db and table
	//getImageFromCMS();

	QmlDocument *qml =
			QmlDocument::create("asset:///SplashScreen_EN.qml").parent(this);
	qml->setContextProperty("_myClass", this);
	AbstractPane *root = qml->createRootObject<AbstractPane>();

	app->setScene(root);
	
	QFutureWatcher<void> m_futureWatcher;
	connect(&m_futureWatcher, SIGNAL(finished()),this, SLOT(onThreadFinished()));
	QFuture<void> result = QtConcurrent::run(this,&Home::formJsonRequestForSection);

  m_futureWatcher.setFuture(result);

   emit activityStopSignal();

}

 

void Home::onThreadFinished(){
	QFutureWatcher<void> m_futureWatcher;
	QFuture<void> result = QtConcurrent::run(this,&Home::formJsonRequestForHowTo);
	m_futureWatcher.setFuture(result);
}

void Home::formJsonRequestForSection(){
	 secID = "1";
		QString upDate = "2013-06-12";
		QString pformId = "4";

		QString temp("{\n\"sectionId\":");
		temp.append("\"" + secID + "\"\n");

		temp.append(",\"platformId\":");
		temp.append("\"" + pformId + "\"\n");

		temp.append(",\"updateDate\":");
		temp.append("\"" + upDate + "\"\n}");

		postJsonRequests(temp,secID);
}

void Home::postJsonRequests(QString temp,QString secId) {


	QString url = "http://192.168.1.241:8080/Webservice/update/section";
	QNetworkAccessManager *manager = new QNetworkAccessManager(this);
	QNetworkRequest request(url);
	request.setHeader(QNetworkRequest::ContentTypeHeader,
			QVariant(QString("application/json;charset=UTF-8")));
	request.setRawHeader("Accept", "application/json");

	QByteArray data;
	data.append(temp);
	qDebug() << url << temp;
	connect(manager, SIGNAL(finished(QNetworkReply*)), this,SLOT(replyFinished(QNetworkReply *)));

	QNetworkReply* reply = manager->post(request, data);
	if (reply) {

	}

}

void Home::replyFinished(QNetworkReply * netReply) {

	if (netReply->error() == QNetworkReply::NoError) {
		QString responsejson = QString::fromUtf8(netReply->readAll());
		qDebug() << "readAll" + responsejson;
		jsonParser(responsejson,secID);
	}
}

void Home::jsonParser(QString str,QString secId)

{
//here data is parsed and inserted into the DB using INSERT query
}

 Culd someone tell me if I am doing it in the right way?

Please like this if you are answered.
Developer
Posts: 17,011
Registered: ‎07-29-2008
My Device: Z10 LE, Z30, Passport
My Carrier: O2 Germany

Re: Issue with QtConcurrent for multithreading

why do you want to use multiple threads here? appending a few strings won't be taking a lot of time, and networking is asynchronous anyhow.

if you want to parse the data and insert it into the database a QtConcurrent::run seems reasonable, i am using it for the same purpose.
----------------------------------------------------------
feel free to press the like button on the right side to thank the user that helped you.
please mark posts as solved if you found a solution.
@SimonHain on twitter
Developer
Posts: 134
Registered: ‎04-12-2013
My Device: BB Z10
My Carrier: Telenor

Re: Issue with QtConcurrent for multithreading

Hi Simon,

 

Thanks, I need to parse the data and insert it into the database. If I dont use multithreading here, the reponses for 4 JSON queries are received first and then the QNetworkReply emits the finished signal. then the current behaviour is, all these reponses will be inserted into one table. I need each response to be inserted into the corresponding table in the database. 

Please like this if you are answered.
Developer
Posts: 134
Registered: ‎04-12-2013
My Device: BB Z10
My Carrier: Telenor

Re: Issue with QtConcurrent for multithreading

Simon,

 

Could you share a code sample if you dnt mind.. for this kind of calls..  

Please like this if you are answered.
Developer
Posts: 17,011
Registered: ‎07-29-2008
My Device: Z10 LE, Z30, Passport
My Carrier: O2 Germany

Re: Issue with QtConcurrent for multithreading

I don't have an overview of what you want to achieve, but if you want me to guess i'd try it like this:

make a network request, connect its signals
receive the reply, disconnect the signals
use QtConcurrent::run to parse the response and write it into the database.
make a new network request etc.

be aware of the possibility of multiple qtconcurrent methods accessing the db at once, use QMutex if you have to safeguard against that.
----------------------------------------------------------
feel free to press the like button on the right side to thank the user that helped you.
please mark posts as solved if you found a solution.
@SimonHain on twitter
New Contributor
Posts: 7
Registered: ‎02-24-2013
My Device: BlackBerry Z10 & Q10
My Carrier: Maxis

Re: Issue with QtConcurrent for multithreading

[ Edited ]

Hi there, 

 

The flow that you implemented is wrong.

Try the below suggested fix:

 

1. You dont need to implement thread for postJsonRequests as you are currently using QNetworkAccessManager to retrieve the JSON.

 

Remove the below code:

QFutureWatcher<void> m_futureWatcher;
	connect(&m_futureWatcher, SIGNAL(finished()),this, SLOT(onThreadFinished()));
	QFuture<void> result = QtConcurrent::run(this,&Home::formJsonRequestForSection);

  m_futureWatcher.setFuture(result);

 and right away call:

formJsonRequestForSection();

 2. You should call the formJsonRequestForHowTo using the thread during the replyFinished

void Home::replyFinished(QNetworkReply * netReply) {

	if (netReply->error() == QNetworkReply::NoError) {
		QString responsejson = QString::fromUtf8(netReply->readAll());
		qDebug() << "readAll" + responsejson;
		jsonParser(responsejson,secID);
	}
       QFutureWatcher<void> m_futureWatcher;
	QFuture<void> result = QtConcurrent::run(this,&Home::formJsonRequestForHowTo);
	m_futureWatcher.setFuture(result);
}

 However if formJsonRequestForHowTo will be using the same method to grab the JSON, there is no need to implement QFuture and QFutureWatcher

Regards,

Syam

Developer
Posts: 134
Registered: ‎04-12-2013
My Device: BB Z10
My Carrier: Telenor

Re: Issue with QtConcurrent for multithreading

Thanks man202. 

Yes, I am using the same function for parsing the JSON. And I have for JSON requests and four functions for each. 

 

So do you mean to say that, I can just call the other functions in the replyfinished?

 

like this,

void Home::replyFinished(QNetworkReply * netReply) {

	if (netReply->error() == QNetworkReply::NoError) {
		QString responsejson = QString::fromUtf8(netReply->readAll());
		qDebug() << "readAll" + responsejson;
		jsonParser(responsejson,secID);
	}
       formJsonRequestForHowTo;
       formJsonRequestForDetail;
       formJsonRequestForVideo;

}

 

Please like this if you are answered.
Highlighted
New Contributor
Posts: 7
Registered: ‎02-24-2013
My Device: BlackBerry Z10 & Q10
My Carrier: Maxis

Re: Issue with QtConcurrent for multithreading

Yes that's how it supposed to work. Do try and let us know the result.