对于多个同时发出的请求,AsyncTask似乎正在冻结

问题描述 投票:0回答:1

我在这里遇到一种情况,当使用AsyncTask通过TCP套接字发送消息序列时,除了5个请求中的2个,其他消息都没有通过网络发送。我也使用Wireshark进行数据包捕获,但没有成功。

这是代码(所有这些方法都在Service类中)。 doTask()是使用AsyncTasks通过tcp套接字发送消息的*方法。我甚至使用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
}
android-asynctask
1个回答
0
投票

在你的“不工作的例子”中,你创建了5个不同的AsyncTask,每个都在tcpsocketOutputStream上发送一条消息。这些任务中的每一个都或多或少同时异步执行(取决于可用的CPU内核数量)。我假设tcpsocketOutputStream不适合发出sendPreparedMessage(msg),如果它还没有完成发送前一个。

如何在一次调用中只创建一个AsyncTask并提供所有5个消息?

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

在doInBackground方法中,您可以在循环中发送收到的5条消息。

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

或者每个异步任务都必须为自己的任务打开套接字连接。

© www.soinside.com 2019 - 2024. All rights reserved.