WCF:方法在生成线程进行后台处理后返回响应

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

所以我有以下场景。我的 WCF 中有一个方法,客户端将在其中发送请求,然后 WCF 服务将执行一些后台处理并调用外部 Web 服务方法,并且该方法将立即响应确认(在后台处理完成之前) )。

我想到的方法是让我的 WCF 方法在生成线程进行后台处理后返回响应,并调用外部 Web 服务。流程是这样的:

  • 主叫方向 INITIAL_CALL 发送请求

  • WCF启动一个调用PROCESS的线程

  • WCF 返回 true

  • PROCESS 调用 EXTERNALWS 并在 postResponse 中获取响应

  • postReponse 被记录到数据库

请参阅下面的示例代码:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class Service : IService


public bool INITIAL_CALL()
{

     new Thread(()=>
                {
                    PROCESS();
                }).Start();
    return true;
}


private void PROCESS()
{
    //Do some background processing and create request for call below
    var processRequest = "Request goes here";
    using (var client = new EXTERNALWS.ResponseTypeClient())
    {
       var postResponse = client.POST(processRequest);

       //Log postResponse to database

    }

}

考虑到 PROCESS() 可能会运行很长时间,我只是想看看是否有更好的方法使用 WCF 和 IIS 来执行此操作?或者如果有任何我必须考虑的陷阱,即 IIS 应用程序池回收会破坏线程。

asynchronous wcf iis background-process application-pool
1个回答
0
投票

我已经找到了解决方案。我最终使用 Hangfire 进行所需的后台处理(https://www.hangfire.io/)。 Hangfire 似乎是专门为此而设计的。我按照他们主页上的文档在一个单独的 ASP MVC 应用程序中实现了它。我还将其配置为始终在 IIS 上运行。设置 Hangfire 来执行此操作的所有说明和示例代码都可以在此处找到https://docs.hangfire.io/en/latest/index.html。我必须更改流程(因为我没有像以前那样手动生成任何新线程),并且还在数据库中创建一个新表,以便 WCF 应用程序中的 INITIAL_CALL 将对所有长时间运行的作业进行排队(稍后将被拾取)并由 Hangfire 处决)。请记住,这与 Hangfire 的队列是分开的,Hangfire 将在预定义的时间间隔内检查此表,并将检查此数据库表,该表存储要调用的函数、其参数以及指示符(如果作业已由 Hangfire 拾取)是否 Hangfire(以避免此处描述的重入场景https://docs.hangfire.io/en/latest/best-practices.html)。有点额外的工作,但效果很好。

现在流程的工作方式如下:

  • 主叫方向 INITIAL_CALL 发送请求

  • 在 INITIAL_CALL 中,在新的数据库表中创建一个条目(这是作业 Hangfire 将按预定义的时间间隔检查的队列)。

  • INITIAL_CALL 返回 true

  • Hangfire 使用 PROCESS_JOBS 以预定义的时间间隔检查此数据库表(此时间间隔可以在 Hangfire 本身中定义)。

  • 如果有排队项目,PROCESS_JOBS 会继续调用 EXTERNALWS 并在 postResponse 中获取响应。如果没有,它只是退出并且不做任何进一步的事情。

  • postReponse 被记录到数据库中。

请参阅下面更新的示例代码:

WCF申请

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class Service : IService


public bool INITIAL_CALL()
{
   //Add job queue entry in database table to be picked up by Hangfire 
    return true;
}

Hangfire 应用程序

public void PROCESS_JOBS()
{
    //Check in a predefined interval if there is a pending job in the queue. 
    //If there is continue with below, otherwise exit function.

    //Do some background processing and create request for call below
    var processRequest = "Request goes here";
    using (var client = new EXTERNALWS.ResponseTypeClient())
    {
       var postResponse = client.POST(processRequest);

       //Log postResponse to database

    }

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