我正在编写一个企业Java应用程序,它使用异步EJB 3.1方法并行执行许多任务。为了支持取消长时间运行的任务,我一直在尝试使用Future接口。
不幸的是,从客户端应用程序调用{{1}}似乎对执行任务的bean的会话上下文没有影响,尽管取消调用正在返回future.cancel(true)
。
我有一个简单的界面:
true
使用如下bean实现:
public interface AsyncInterface
{
Future<Integer> run() throws Exception;
}
客户端代码很简单:
@Stateless
@Remote(AsyncInterface.class)
public class AsyncBean
{
@Resource SessionContext myContext;
@Asynchronous
public Future<Integer> run() throws Exception
{
Integer result = 0;
System.out.println("Running AsyncBean");
while(myContext.wasCancelCalled() == false)
{
Thread.sleep(2000);
System.out.println("Working");
}
System.out.println("AsyncBean cancelled");
return new AsyncResult<Integer>(result);
}
}
bean的输出是“工作”的源源不断;它永远不会检测到取消。
如果它是相关的,我正在JBoss Application Server 6.0.0上运行该应用程序。我没有找到使用Future接口的取消功能的示例代码,所以我想知道我是否正确使用Future。这种用法看起来是否正确?是否有更好的选择来取消异步EJB方法调用?
答案 0 :(得分:3)
回答我自己的问题 - 我发现JBoss AS 6.0.0不支持异步请求的计算。
作为替代方案,我重构了代码以使用JMS请求/响应样式消息传递。
消息驱动bean用于执行异步操作。消息驱动bean创建一个临时队列,并通过JMS将队列返回给调用者。这是通过利用JMS消息的replyTo字段来实现的。
消息驱动bean然后定期检查临时队列中的取消消息。
这比@Asynchronous版本更复杂,但它适用于JBoss AS 6.0.0。
答案 1 :(得分:2)
您必须return
Future
类型的对象,而不是null
。顺便问一下,你没有获得NPE吗?我希望你的代码有问题。
此外,不应调用cancel()
。 See the docs here。顺便说一句,根据docs,不仅不应该调用cancel()
方法,也不应该调用实例方法。这就引出了一个问题,那就是为什么一个方法应该返回AsyncResult
。我根本不知道,可能是它的未来用途。但是class level comments表明所有方法都是为了方便将结果提供给容器。
因此,我不确定是否可以取消异步EJB调用。
[经过一点研究后编辑]
试试这个实现,
@Stateless
@Remote(AsyncInterface.class)
public class AsyncBean
{
@Resource SessionContext myContext;
@Asynchronous
public Integer run() throws Exception
{
Integer result = 0;
System.out.println("Running AsyncBean");
while(myContext.wasCancelCalled() == false)
{
Thread.sleep(2000);
System.out.println("Working");
}
System.out.println("AsyncBean cancelled");
return result;
}
}