You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Acumatica中Contract Soap API调用含PXLongOperation的操作触发未完成异常

解决Acumatica Contract SOAP API调用含PXLongOperation的Release方法时的异常问题

我之前也碰到过一模一样的场景,这个问题的核心矛盾在于PXLongOperation的异步特性和Contract API的同步执行模型不兼容,下面给你拆解原因和可行的解决方案:

问题根源

  • 当在UI中使用PXLongOperation时,Acumatica的UI会话会单独管理后台异步任务,允许用户继续操作其他功能,不会阻塞当前会话的交互。
  • 但Contract SOAP API是单次同步请求,它的会话生命周期和请求完全绑定:API调用发起后,Acumatica会创建临时会话,操作执行完成后立即回收会话。而PXLongOperation是在后台独立线程执行的,当API请求结束时,长操作可能还在运行,此时系统检测到当前会话有未完成的异步操作,就会抛出「The previous operation has not been completed yet.」异常。

解决方案

根据Acumatica的最佳实践,我们可以通过**区分执行上下文(UI/API)**来适配不同的执行方式:

方案1:针对API调用同步执行自定义逻辑

如果你的外部Web服务调用耗时不长,直接在API请求周期内同步执行自定义流程,避免异步操作冲突。代码示例如下:

[PXOverride]
public IEnumerable Release(PXAdapter adapter, ReleaseDelegate baseMethod)
{
    ARInvoice invoice = Base.Document.Current;
    CtpARInvoiceExt invoiceExt = PXCache<ARInvoice>.GetExtension<CtpARInvoiceExt>(invoice);
    
    // 判断当前是否为Contract API调用
    bool isContractAPI = PXAccess.FeatureInstalled<FeaturesSet.contractBasedAPI>() 
                         && HttpContext.Current != null 
                         && HttpContext.Current.Request.Path.Contains("/entity/");

    if (invoice.DocType == "CRM")
    {
        if (isContractAPI)
        {
            // API场景:同步执行自定义流程,避免异步冲突
            ProcessClickToPayCreditMemoInvoice(invoice, invoiceExt);
        }
        else
        {
            // UI场景:使用PXLongOperation避免UI阻塞
            PXLongOperation.StartOperation(Base, () => { ProcessClickToPayCreditMemoInvoice(invoice, invoiceExt); });
        }
    }

    try
    {
        return baseMethod(new PXAdapter(Base.CurrentDocument));
    }
    catch (Exception e)
    {
        throw new PXException(e, CtpMessages.ClickToPayReleaseOverrideFailed, e.Message);
    }
    finally
    {
        // 你的退出逻辑
    }
}

方案2:用Acumatica异步任务框架替代PXLongOperation(适合长耗时操作)

如果外部Web服务调用耗时很长,同步执行会导致API超时,建议把自定义流程封装成独立的异步处理任务:

  1. 创建一个自定义DAC(比如CtpInvoiceProcessingTask),存储需要处理的发票ID、状态等信息。
  2. 在Release方法中,插入一条任务记录,然后通过PXProcessing框架触发后台处理。
  3. 编写专门的处理图(比如CtpInvoiceProcessingMaint)来执行ProcessClickToPayCreditMemoInvoice逻辑。

这种方式下,API调用只需提交任务即可立即返回,后台任务独立于API会话执行,不会触发异常。

测试注意事项

  • 修改代码后,重新发布Acumatica实例,清除缓存。
  • 分别测试UI操作和API调用场景,确保两种路径都能正常执行:
    • UI端:释放发票时,自定义流程在后台异步执行,UI不会阻塞。
    • API端:调用Release接口时,自定义流程同步完成(或任务提交成功),不会抛出未完成操作的异常。

内容的提问来源于stack exchange,提问作者Robert Waite

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:55:22