我有一个不断运行处理数据的服务,它通过消息传递接收处理新数据的请求。当它忙于处理新的请求时,它们会被合并在一起,这样它们就会被同时处理。AutoResetEvent 用于通知处理器有新请求可用。
我的问题是在 EventLoop 中,WaitOne 之后的 currentRequest 是否有可能为空?
将 _eventAvailable.Set() 放在 lock(_eventLocker) 之外是不好的做法吗?我把它移了出来,这样它就不会开始在 WaitOne 上运行,并立即对锁(_eventLocker)进行竞争。
关于如何更好地编写以下代码的任何建议?
public sealed class RealtimeRunner : MarshalByRefObject
{
/// <summary>
/// The actual event, new events get merged into this if it is not null
/// </summary>
private Request _pendingRequest;
/// <summary>
/// Used to signal the runner thread when an event is available to process
/// </summary>
private readonly AutoResetEvent _eventAvailable = new AutoResetEvent(false);
private readonly object _eventLocker = new object();
/// <summary>
/// Called on a background thread via messaging
/// </summary>
public void QueueEvent(RealtimeProcessorMessage newRequest)
{
bool mergedRequest;
lock (_eventLocker)
{
if (_pendingRequest == null)
{
mergedRequest = false;
_pendingRequest = new Request(newRequest, _engine);
}
else
{
mergedRequest = true;
_pendingRequest.Merge(newRequest, _engine);
}
}
_eventAvailable.Set();
}
/// <summary>
/// This is running on its own thread
/// </summary>
private void EventLoop()
{
while (true)
{
// Block until something exists in _pendingRequest
_eventAvailable.WaitOne();
Request currentRequest;
lock (_eventLocker)
{
currentRequest = _pendingRequest;
_pendingRequest = null;
}
// CAN THIS EVER BE NULL?
if (currentRequest == null)
continue;
//do stuff with the currentRequest here
}
}
}