具有并发任务(可能受到限制)的单实例WCF服务

本文关键字:单实例 实例 服务 WCF 受到限制 并发 任务 | 更新日期: 2023-09-27 18:00:12

我正在尝试构建一个WCF服务,该服务-

  1. 是单个实例
  2. 允许客户端对功能(例如StartJob)发出多个请求
  3. StarJob(请求)将请求"排队"到按并发任务计划运行的TaskFactory(一个实例)(根据示例实现

  4. 任务工厂中的任务完成后,返回响应

  5. 当一个任务正在运行并且有更多的请求进入时,它们会被排队(如果达到最大并发数)

目标是构建一个系统,接受来自客户端的请求并将其排队等待处理。

目前,我的代码(如下所示)在不考虑任务调度程序的最大并发数的情况下同时运行所有请求。

问题

  1. 我错过了什么
  2. 我能看看什么好的例子/参考资料吗?(我相信这不是一个罕见的用例)

代码

I服务

[ServiceContract]
public interface ISupportService
{
    [OperationContract]
    Task<TaskResponse> StartTask(TaskRequest taskRequest);
}

服务

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class SupportService : ISupportService
{
    private static TaskRequestHandler taskRequestHandler;
    public SupportService()
    {        
        taskRequestHandler = TaskRequestHandler.GetInstance();         
    }
    public Task<TaskResponse> StartTask(TaskRequest taskRequest)
    {
        var tcs = new TaskCompletionSource<TaskResponse>();
        if (!IsTaskRequestValid(taskRequest))
            tcs.SetResult(new TaskResponse()});
        taskRequestHandler.StartTaskAsync(taskRequest, lockHandler).ContinueWith(task => { tcs.SetResult(task.Result); });
        return tcs.Task;
    }    
}

任务请求处理程序

public class TaskRequestHandler
{
    private ConcurrentTaskScheduler taskScheduler;
    private TaskFactory taskFactory;
    private TaskRequestHandler()
    {
        taskScheduler = new ConcurrentTaskScheduler(2);
        taskFactory = new TaskFactory(taskScheduler);
    }
    private Task<TaskResponse> StartTaskAsync (TaskRequest request, LockHandler lockHandler)
    {
        var tcs = new TaskCompletionSource<TaskResponse>();
        taskFactory.StartNew(() =>
        {
            //Some task with tcs.SetResults()
        });
        return tcs.Task;
    }
}

具有并发任务(可能受到限制)的单实例WCF服务

Aaaah!对我来说是个大失误。在taskFactory中执行的操作比我预期的要完成。因此,所有任务似乎都是并行运行的。

我更新了操作代码,以正确地监控操作完成情况并引发正确的回调,上面的代码运行良好。

然而,做了一个小改动-

  • CCD_ 2不需要返回CCD_ 3。相反,只返回TaskResponse就足够了(因为WCF负责每个OperationContract的异步和同步功能)