如何在多个处理器之间分配工作?

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

我有一个执行一些数据处理的类:

class Processor
{
    public Processor() {
        // Load lot of data
    }
    public string GetResult(string input) {
        // ... 
    }
}

我需要实现一个向此类公开 HTTP API 的服务。我使用 Owin 和 Microsoft.AspNet.* 库来托管 HTTP Web API。对于每个请求,它都会创建一个新线程来处理它,但我无法在每个请求上实例化

Processor
,因为在其构造函数中加载一些数据需要花费大量时间。另外,我无法重用不同线程中的一个实例,因为它不是设计为线程安全的。但我可以在服务启动时实例化
Processor
的多个实例,然后在它们之间分派工作。假设我的服务最多允许 20 个并发 HTTP 请求。我创建 20 个
Processor
实例并向类添加 Busy 标志:

class Processor
{
    public bool Busy { get; set; }
    // ...
}

我写了这样的

Dispatcher
类:

class Dispatcher
{
    readonly Processor[] _processors;
    readonly SemaphoreSlim _semaphore;

    public Dispatcher(int maxProcessors)
    {
        _semaphore = new SemaphoreSlim(maxProcessors);
        _processors = new Processor[maxProcessors];
        // Instantiate Processors, etc...
    }

    public string GetResult(string input)
    {
        try
        {
            _semaphore.Wait(); // Surplus requests will wait here.
            Processor processor;
            lock (_processors)
            {
                // It is guaranteed that such processor exists if we entered the semaphore.
                processor = _processors.First(p => !p.Busy);
                processor.Busy = true;
            }
            var result = processor.GetResult(input);
            processor.Busy = false;
            return result;
        }
        finally
        {
            _semaphore.Release();
        }
    }
}

然后我基本上就可以在ApiController中通过

Dispatcher
来调用了:

public class ServiceController : ApiController
{
    static Dispatcher _dispatcher = new Dispatcher(20);

    [Route("result")]
    [HttpGet]
    public string Result(string input)
    {
        return _dispatcher.GetResult(input);
    }
}

它是否正确实现了我的目的? 我测试了它并且它有效,但我想知道我是否重新发明了轮子并且 .NET Framework 已经准备好用于我的案例,或者它是否可以更容易地实现。

c# .net multithreading asp.net-web-api
1个回答
0
投票

基本上在将在线程中运行的类中,创建一个事件和事件处理程序。然后启动该任务的对象可以注册该事件。当任务引发它时(在这种情况下,您将在完成时引发事件),您可以做一些事情,即。给它更多的工作。

在将在子线程中运行的类中创建事件:


        public event TaskCompleteEventHandler OnComplete;
        public event TaskErrorEventHandler OnError;

在正在旋转类的对象中注册事件:

task.OnComplete += TaskComplete;
task.OnError += TaskComplete;

在调用类中创建将处理事件的函数:

public void TaskComplete()
{
//give the thread more work
}
© www.soinside.com 2019 - 2024. All rights reserved.