我有一个处理队列数据的服务:
while (true)
{
if(!HaltProcessing)
{
var messages = receivedQueue.GetMessages(MessageGetLimit);
if (messages.Count() > 0)
{
ProcessQueueMessages(messages);
}
else
{
Task.Delay(PollingInterval);
}
}
}
有一个HaltProcessing
属性,当设置为true时,暂停队列项的处理。我是通过if statement
完成的,如上所示。
在HaltProcessing
为true
时阻止线程是否有更好的方法,在false
时阻止线程?
答案 0 :(得分:3)
是的,您可以使用“WaitHandles”。
AutoResetEvent或ManualRestEvent来实现它。
private ManualRestEvent signal = new ManualRestEvent(false);//or true based on your req
//Setting true is to allow processing and false is to halt the processing
while (true)
{
signal.WaitOne();
var messages = receivedQueue.GetMessages(MessageGetLimit);
if (messages.Count() > 0)
{
ProcessQueueMessages(messages);
}
else
{
Task.Delay(PollingInterval);
}
}
bool SetHaltProcessing(bool value)
{
if(value)
signal.Reset();
else
signal.Set();
}
用例
SetHaltProcessing(true);//To halt the processing
SetHaltProcessing(false);//To start the processing
答案 1 :(得分:2)
我建议你退一步看看更大的图片:如果设置了HaltProcessing
,你不需要(并希望)循环运行。
所以我的方法是将逻辑放入HaltProcessing
setter:
实现这个:
答案 2 :(得分:1)
Task.Delay()
将不会执行任何操作,将返回一个Task
,它将在给定的间隔后完成。如果您对Task
没有做任何事情,那就好像你没有打电话一样。如果要在集合中处理集合中的项目并在集合为空时阻止,则应使用BlockingCollection
。
在收集空的时候等待一段时间是不好的,原因有两个:
Count
。如果您希望等到HaltProcessing
为true
,则可以使用ManualResetEventSlim
。虽然否则这样做更自然:
private ManualResetEventSlim processingAllowedEvent =
new ManualResetEventSlim(true);
public bool ProcessingAllowed
{
get
{
return processingAllowedEvent.IsSet;
}
set
{
if (value)
processingAllowedEvent.Set();
else
processingAllowedEvent.Reset();
}
}
public void WaitUntilProcessingAllowed()
{
processingAllowedEvent.Wait();
}
有了这一切,你的循环看起来像这样:
while (true)
{
WaitUntilProcessingAllowed();
ProcessQueueMessage(blockingCollection.Take());
}
这假设您可以在ProcessingAllowed
设置为false
后处理一个项目。如果不是这样,则需要更复杂的同步(可能使用CancellationToken
)。
答案 3 :(得分:0)
你确实意识到你所做的只是在那个循环中不断运行,检查HaltProcessing
是否为真,当它是假的时候,你处理的东西......那是忙着等待它最好的,而且它不漂亮
你应该有一些逻辑说: