Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/294.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 重复性任务需求情况下的备选方案_C#_.net_Task_Task Parallel Library_Polling - Fatal编程技术网

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并帮助调度程序。