AsyncTask, кажется, зависает для нескольких одновременных запросов - PullRequest
0 голосов
/ 17 февраля 2019

Здесь я сталкиваюсь с ситуацией, когда при отправке последовательности сообщений через сокет TCP с помощью AsyncTask, за исключением 2 из 5 запросов, ни одно из других сообщений не отправляется по сети.Я также сделал захват пакета с помощью Wireshark, но безуспешно.

Вот код (все эти методы в классе обслуживания).doTask () - это метод * для отправки сообщений через tcp-сокет с использованием AsyncTasks.Я даже использовал ThreadPool, но безуспешно.

private class SendMessage extends AsyncTask<EASMessageBase, Void, Void> {
        @Override
        protected Void doInBackground(EASMessageBase... easMessageBases) {
            EASMessageBase msg = easMessageBases[0];
            try {
                //send data over tcp socket output stream
                tcpsocketOutputStream.sendPreparedMessage(msg);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
    }

//DIDN'T WORK EXCEPT FIRST 2 REQUESTS
//without wait statement
public void doTask() {
    new SendMessage().execute(message1);
    new SendMessage().execute(message2);
    new SendMessage().execute(message3);
    new SendMessage().execute(message4);
    new SendMessage().execute(message5);
}

//WORKED
//using wait statement
public void doTask() {
    new SendMessage().execute(message1);
    sleep();
    new SendMessage().execute(message2);
    sleep();
    new SendMessage().execute(message3);
    sleep();
    new SendMessage().execute(message4);
    sleep();
    new SendMessage().execute(message5);
}

private void sleep() {
    try { 
        Thread.currentThread().sleep(500);
    }
    catch(Exception e){

    }
}

//DIDN'T WORK EXCEPT FOR FIRST 2 REQUESTS
//using handlers without timeout
public void doTask() {
Handler handler = new Handler(Looper.getMainLooper());
//message 1
handler.post(new Runnable() {
    @Override
    public void run() {
        new SendMessage().execute(message1);
    }
});

//message 2
handler.post(new Runnable() {
    @Override
    public void run() {
        new SendMessage().execute(message2);
    }
});

//message 3
//message 4
//message 5
}


//THIS METHOD WORKED
/*using handlers with timeout (used same timeout, and incremental timeout for each message as well)
1. used same timeout for all messages (e.g. 200)
2. used incremental timeouts for all messages (e.g. 200 for message1, 300 for message2, etc)
*/
public void doTask() {
Handler handler = new Handler(Looper.getMainLooper());

//message1
handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            new SendMessage().execute(message1);
        }
    }, 200);

//message2
//message3
//message4
//message5
}

1 Ответ

0 голосов
/ 17 февраля 2019

В вашем «неработающем примере» вы создаете 5 разных AsyncTask, каждый из которых отправляет одно сообщение в tcpsocketOutputStream.Каждая из этих задач выполняется асинхронно, более или менее одновременно (в зависимости от того, сколько доступно процессорных ядер).Я предполагаю, что tcpsocketOutputStream не подходит для выдачи sendPreparedMessage (msg), если он еще не завершил отправку предыдущего.

Как насчет создания только одного AsyncTask и подачи всех 5 сообщений за один вызов?

new SendMessage().execute(message1,message2,message3,message4,message5);

А в методе doInBackground вы отправляете полученные 5 сообщений в цикле.

for (EASMessageBase msg : easMessageBases)
{
    // send the msg
}

Или каждая ваша асинхронная задача должна открыть соединение с сокетом для своего собственного.

...