SemaphoreSlim 类中的 WaitHandle.WaitOne() 方法无法正常工作

我有一个复杂的情况,但我会尽量缩短它,只知道重要的细节。我正在尝试实现基于任务的作业处理。这是课程:


internal class TaskBasedJob : IJob

{

    public WaitHandle WaitHandle { get; }

    public JobStatus Status { get; private set; }

    public TaskBasedJob(Func<Task<JobStatus>> action, TimeSpan interval, TimeSpan delay)

    {

         Status = JobStatus.NotExecuted;

        var semaphore = new SemaphoreSlim(0, 1);

        WaitHandle = semaphore.AvailableWaitHandle;


        _timer = new Timer(async x =>

        {

            // return to prevent duplicate executions

            // Semaphore starts locked so WaitHandle works properly

            if (semaphore.CurrentCount == 0 && Status != JobStatus.NotExecuted)

            {

                return;

                Status = JobStatus.Failure;

            }


            if(Status != JobStatus.NotExecuted)

                await semaphore.WaitAsync();


            try

            {

                await action();

            }

            finally

            {

                semaphore.Release();

            }


        }, null, delay, interval);

    }

}

以下是调度程序类:


internal class Scheduler : IScheduler

{

    private readonly ILogger _logger;

    private readonly ConcurrentDictionary<string, IJob> _timers = new ConcurrentDictionary<string, IJob>();


    public Scheduler(ILogger logger)

    {

        _logger = logger;

    }


    public IJob ScheduleAsync(string jobName, Func<Task<JobStatus>> action, TimeSpan interval, TimeSpan delay = default(TimeSpan))

    {

        if (!_timers.ContainsKey(jobName))

        {

            lock (_timers)

            {

                if (!_timers.ContainsKey(jobName))

                    _timers.TryAdd(jobName, new TaskBasedJob(jobName, action, interval, delay, _logger));

            }

        }


        return _timers[jobName];

    }


    public IReadOnlyDictionary<string, IJob> GetJobs()

    {

        return _timers;

    }

}

在这个库里面,我有一个像下面这样的服务:所以这个服务的想法只是在被调用的字典_accessInfos和它的异步方法中获取一些数据。您可以在构造函数中看到我已经添加了获取数据的作业。


守着一只汪
浏览 236回答 1
1回答

MMMHUHU

Rajmond 的同事在这里。我弄清楚我们的问题。基本上,等待工作正常等等。我们的问题很简单,如果你这样做,IServiceCollection.BuildServiceProvider()你每次都会得到不同的范围(因此即使使用 Singleton 实例也会创建不同的对象)。试试这个的简单方法:var serviceProvider1 = services.BuildServiceProvider();var hashCode1 = serviceProvider1.GetService<IAccessInfoStore>().GetHashCode();var hashCode2 = serviceProvider1.GetService<IAccessInfoStore>().GetHashCode();var serviceProvider2 = services.BuildServiceProvider();var hashCode3 = serviceProvider2.GetService<IAccessInfoStore>().GetHashCode();var hashCode4 = serviceProvider2.GetService<IAccessInfoStore>().GetHashCode();hashCode1andhashCode2相同,与hashCode3and相同hashCode4(因为单例),但hashCode1/hashCode2与hashCode3/hashCode4不同(因为不同的服务提供者)。真正的修复可能是检查 IAccessInfoStore,它会在内部阻塞,直到作业第一次完成。干杯!
打开App,查看更多内容
随时随地看视频慕课网APP