我有一个软件可以根据excel文件生成SOAP请求,然后通过电子邮件发送结果。
由于请求的可能大小,我并行执行soap-request-handling。以下代码处理上述内容。
public void HandleData() {
List<NodeAnalysisReply> replies = Collections.synchronizedList(new ArrayList<>());
new Thread(() -> {
List<NodeAnalysisRequest> requests;
SOAPMessageFactory factory = new SOAPMessageFactory();
SOAPResponseParser parser = new SOAPResponseParser();
try {
requests = new ExcelParser().parseData(file);
requests.parallelStream().forEach((request) -> {
try {
SOAPMessage message = factory.createNodeRequestMessage(
new RequestObject(requestInfoFactory.makeInfo(trackingID), request));
SOAPMessage response = new SoapConnector(server.getUrl()).executeRequest(message);
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.writeTo(out);
NodeAnalysisReply curReply = parser.ParseXMLResponse(out.toString(), request);
synchronized (replies) {
System.out.println("Adding: " + curReply.getRequest().toString());
replies.add(curReply);
}
} catch (UnsupportedOperationException | SOAPException | IOException e) {
handleSoap(e.getMessage());
}
});
} catch (IOException e) {
handleBadParse();
}
try {
for(NodeAnalysisReply reply : replies){
System.out.println("Data: " + reply.getRequest().toString());
}
mailer.SendEmail("Done", email, replies);
} catch (MessagingException e) {
e.printStackTrace();
}
}).start();
}
当我使用两段数据运行代码时,会发生以下情况:
Adding: Søndergade 52 6920 // OK
Adding: Ternevej 1 6920 // OK
Data: Ternevej 1 6920 // What
Data: Ternevej 1 6920 // WHAT..
are equal? true
所以尽管它将两个项目都添加到列表中,但似乎最后一个项目占据了两个位置。那怎么回事,我该怎么解决呢? - 我确实错过了Parrallel.ForEach()表单C#!
编辑:根据要求,NodeAnalysisReply的代码。
public class NodeAnalysisReply {
public ReplyInfo getReplyInfo() {
return replyInfo;
}
public void setReplyInfo(ReplyInfo replyInfo) {
this.replyInfo = replyInfo;
}
public List < nodeAnalysisListDetails > getNodeAnalysisListDetails() {
return nodeAnalysisListDetails;
}
public void setNodeAnalysisListDetails(List < nodeAnalysisListDetails > nodeAnalysisListDetails) {
this.nodeAnalysisListDetails = nodeAnalysisListDetails;
}
public void addNodeAnalysisListDetail(nodeAnalysisListDetails nodeAnalysisListDetails) {
this.nodeAnalysisListDetails.add(nodeAnalysisListDetails);
}
ReplyInfo replyInfo;
public String getFormattedXML() {
return formattedXML;
}
public void setFormattedXML(String formattedXML) {
this.formattedXML = formattedXML;
}
String formattedXML;
public NodeAnalysisRequest getRequest() {
return request;
}
public void setRequest(NodeAnalysisRequest request) {
this.request = request;
}
NodeAnalysisRequest request;
List < nodeAnalysisListDetails > nodeAnalysisListDetails = new ArrayList < > ();
}
答案 0 :(得分:0)
synchronized (replies) {
System.out.println("Adding: " + curReply.getRequest().toString());
replies.add(curReply);
}
流中的lambda中的上述代码称为副作用,根本不鼓励。
你应该做的事情如下。
replies.addAll(requests.parallelStream().map((request) -> {
try {
SOAPMessage message = factory.createNodeRequestMessage(
new RequestObject(requestInfoFactory.makeInfo(trackingID), request));
SOAPMessage response = new SoapConnector(server.getUrl()).executeRequest(message);
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.writeTo(out);
NodeAnalysisReply curReply = parser.ParseXMLResponse(out.toString(), request);
return curReply;
} catch (UnsupportedOperationException | SOAPException | IOException e) {
handleSoap(e.getMessage());
return null;
}
})
.filter(curReply -> curReply != null)
.collect(Collectors.toList())
);
在上面的代码中,您首先将每个request
映射到NodeAnalysisReply
,然后仅过滤非空值,最后将其收集到列表中以及所有replies
列表中的值