C# 重复性任务需求情况下的备选方案
我有一个观察者模块,它负责订阅我从卡夫卡创建的一些反应流。可悲的是,为了接收卡夫卡的信息,我需要进行民意调查,所以我需要为此专门安排一条背景线索。我的第一个解决方案是:C# 重复性任务需求情况下的备选方案,c#,.net,task,task-parallel-library,polling,C#,.net,Task,Task Parallel Library,Polling,我有一个观察者模块,它负责订阅我从卡夫卡创建的一些反应流。可悲的是,为了接收卡夫卡的信息,我需要进行民意调查,所以我需要为此专门安排一条背景线索。我的第一个解决方案是: public void Poll() { if (Interlocked.Exchange(ref _state, POLLING) == NOTPOLLING) { Task.Run(() => { while (CurrentSubscriptio
public void Poll()
{
if (Interlocked.Exchange(ref _state, POLLING) == NOTPOLLING)
{
Task.Run(() =>
{
while (CurrentSubscriptions.Count != 0)
{
_consumer.Poll(TimeSpan.FromSeconds(1));
}
_state = NOTPOLLING;
});
}
}
现在,我的审阅者建议我应该执行任务,因为它有状态,可以检查它们是否正在运行。这导致了以下代码:
public void Poll()
{
// checks for statuses: WaitingForActivation, WaitingToRun, Running
if (_runningStatuses.Contains(_pollingTask.Status)) return;
_pollingTask.Start(); // this obviously throws exception once Task already completes and then I want to start it again
}
任务基本保持不变,但检查发生了变化,因为我的逻辑是,当我有订阅时,我想开始轮询,当我不需要时,我想停止轮询。我需要重新使用任务,但既然不能,我想知道我是否需要回到我的第一个实现,或者是否有任何其他整洁的方法可以做到这一点,我现在缺少了
我想知道我是否需要回到我的第一个实现,或者是否有其他我现在缺少的简洁的实现方法
您的第一个实现看起来很好。您可以使用ManualResetEventSlim而不是enum和Interlocked.Exchange,但本质上是一样的。。。只要你只有两个状态。我想我做了一个折衷,删除了methodimpl.Options.Synchronized的联锁API。它让我有了简单的方法体,而不可能为最终的新手/没有经验的家伙混淆联锁API代码
[MethodImpl(MethodImplOptions.Synchronized)]
public void Poll()
{
if (!_polling)
{
_polling = true;
new Task(() =>
{
while (_currentSubscriptions.Count != 0)
{
_consumer.Poll(TimeSpan.FromSeconds(1));
}
_polling = false;
}, TaskCreationOptions.LongRunning).Start();
}
}
阅读本文并重新考虑是否使用新任务…开始,同时锁定您正在执行的公开可用指针锁定这也被认为是邪恶的。啊,谢谢,伙计,我想我会使用Task.Factory.StartNew,因为我想提供TaskCreationOptions并帮助调度程序。