我有一个类,它执行一些数据处理:
class Processor
{
public Processor() {
// Load lot of data
}
public string GetResult(string input) {
// ...
}
}
我需要实现一个向这个类公开HTTP API的服务。我使用Owin和Microsoft.AspNet。* libs来托管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已经准备好用于我的情况,或者它是否可以更容易实现。
答案 0 :(得分:0)
基本上在将要在线程中运行的类中,创建一个事件和事件处理程序。然后旋转此任务的对象可以注册到该事件。当它被任务引发时(在这种情况下你会在事件完成时引发事件)你可以做一些事情,即。给它更多的工作。
在将在子线程中运行的类中创建事件:
public event TaskCompleteEventHandler OnComplete;
public event TaskErrorEventHandler OnError;
在正在旋转类的对象中注册您的事件:
task.OnComplete += TaskComplete;
task.OnError += TaskComplete;
在将处理事件的调用类中创建函数:
public void TaskComplete()
{
//give the thread more work
}