c# - 为什么我的代码抛出 `The semaphore has been disposed` 异常?

标签 c# wpf task

在我的代码中,我使用 SemaphoreSlim ,在执行整个 for 循环后,我收到来自 App.g.cs 的异常 信号量已被释放,如果仅通过using语句释放信号量,我无法找出原因。这是使用的整个方法的代码:

public async Task TestHistoricalResultsAsync()
{
    //init values and controls
    CommandStartedControlsSetup("TestResultsCommand");

    List<Task> tasks = new List<Task>();
    int degreeOfParallelism = 10;
    int loopCounter = 0;
    ProgressBarTick("Testing on historic data", loopCounter, Races.Count, 0);
    using (var throttler = new SemaphoreSlim(degreeOfParallelism))
    {
        //for all races in the file
        for (int i = 0; i < Races.Count; i++)
        {
            int j = i;

            if (TaskCancellation == true)
            {
                break;
            }

            await throttler.WaitAsync(TokenSource.Token);

            tasks.Add(Task.Run(() => //async
            {
                try
                {
                    CancellationToken.ThrowIfCancellationRequested();

                    //if the race is from 2018
                    if (Races[j].RaceDate.Year == 2018)
                    {
                        Category = Races[j].RaceCategory;
                        Distance = Races[j].RaceDistance.ToString();

                        //for all horses in the race
                        for (int h = 0; h < Races[j].HorseList.Count; h++)
                        {
                            if (TaskCancellation == true)
                            {
                                break;
                            }
                            CancellationToken.ThrowIfCancellationRequested();
                            HorseDataWrapper horse = new HorseDataWrapper();
                            horse = ParseHorseData(Races[j].HorseList[h], Races[j].RaceDate);
                            Races[j].HorseList[h] = horse; //get all indexes
                        }
                    }
                }
                catch (Exception e)
                {
                    //
                }
                finally
                {
                    loopCounter++;

                    ProgressBarTick("Testing on historic data", loopCounter, Races.Count, 0);

                    throttler.Release();
                }
            }));
        }
    }
    try
    {
        //ThreadPool.SetMinThreads(100, 100);
        await Task.WhenAll(tasks);
    }
    catch (OperationCanceledException)
    {
        //
    }
    finally
    {
        await _dataServices.SaveRaceTestResultsAsync(Races.ToList()); //save the analysis to the file

        AllControlsEnabled = true;

        CommandCompletedControlsSetup();

        VisibilityCancellingMsg = Visibility.Collapsed;
    }
}

最佳答案

根据评论讨论,问题是您的信号量超出了范围。您有两个选择:

a) 等待 block 内所有任务的执行

using (var throttler = new SemaphoreSlim(degreeOfParallelism))
{
    // setup the tasks

    try
    {
        await Task.WhenAll(tasks);
    }
    // ...
}

b) 所有任务执行完成后手动处置

var throttler = new SemaphoreSlim(degreeOfParallelism)
{
    // setup the tasks. You can still use a scope block (brackets) here if you want.
}

try
{
    await Task.WhenAll(tasks);
    // ...
}
finally 
{
    throttler?.Dispose()
}

第二个选项很可能更合适,但这取决于代码的最终布局。

关于c# - 为什么我的代码抛出 `The semaphore has been disposed` 异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56640694/

相关文章:

c# - 通知 View 模型模型已更改(来自组合框)

java - 设计并编写一个任务调度程序,可以接受不同步或同步的任务

c# - 根据多个字段或列从列表中删除重复项

wpf - 多绑定(bind)转换器?

c# 缩小转换不会产生异常

WPF/MVVM - 如何在启动时执行命令?

c# - 如何在多线程中并行运行依赖任务?

python - 应用程序引擎(gae)、python、ndb、延迟库或任务链、cron 作业还是全部?

c# - 在 native SQL 查询中应使用多少列格式?

c# - 图像的 EMGU/OpenCV FFT 未产生预期结果