Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/335.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#_Wpf_Task - Fatal编程技术网

C# 为什么我的代码抛出“信号量已被释放”异常?

C# 为什么我的代码抛出“信号量已被释放”异常?,c#,wpf,task,C#,Wpf,Task,在我的代码中,我使用了SemaphoreSlim,在执行了整个for循环之后,我从App.g.csexception接收到信号量已被释放,如果仅通过使用语句来释放,我无法找出原因。以下是通常使用的整个方法的代码: public async Task TestHistoricalResultsAsync() { //init values and controls CommandStartedControlsSetup("TestResultsCommand"); Lis

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

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;
    }
}
公共异步任务TestHistoricalResultsAsync()
{
//初始化值和控件
CommandStartedControlsSetup(“TestResultCommand”);
列表任务=新列表();
int degreeOfParallelism=10;
int循环计数器=0;
ProgressBarTick(“历史数据测试”,循环计数器,Races.Count,0);
使用(var节流器=新信号量lim(degreeOfParallelism))
{
//对于文件中的所有种族
for(int i=0;i//异步
{
尝试
{
CancellationToken.ThrowIfCancellationRequested();
//如果比赛从2018年开始
如果(比赛[j].RaceDate.Year==2018)
{
类别=种族[j]。种族类别;
距离=赛道[j]。赛道距离。ToString();
//所有参赛的马
对于(int h=0;h
根据评论讨论,问题是您的信号量超出了范围。您有两个选择:

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

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()
}

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

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

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

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()
}

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

因为
throttler
在执行任务之前超出了using语句的范围。关键是任务是异步的,那么为什么要使用
using
块,而该块只有在它们是同步的情况下才能工作呢?如果您真的想,您需要保留
任务。当所有
调用
using
块以防止其被处置时。@ClausJørgensen I基于此示例,您建议使用
摆脱
,并手动处置?或者
Release
正在处理它?好吧,在执行所有任务之前,您不能处理信号量。因此,您需要使用
块等待它们在
内全部完成,或者手动处理。这两种选择都取决于您想要如何构造代码。并注意在示例中,
如何等待Task.WhenAll(tasks)
是在
中使用
block.bakunet调用的:您误解了作用域在C#中的工作方式。基本上,using语句的作用域完成了,因为它内部没有执行任何操作,您只是将块附加到数组中。之后信号量被释放,然后首先执行任务(使用已释放的信号量)。我认为您现在应该只进行手动处理,这样更容易理解作用域是如何以这种方式工作的。(基本上在示例代码的最后一块中处理)
Task.Run
说(基本上)“以后再做”。而
later
是在
Dispose
之后发生的
using
导致的。因为
throttler
在任务执行之前超出了using语句的范围。关键是任务是异步的,那么为什么要使用
using
块,而该块只有在它们是同步的情况下才能工作呢?如果您真的想,您需要保留
任务。当所有
调用
using
块以防止其被处置时。@ClausJørgensen I基于此示例,您建议使用
摆脱
,并手动处置?或者
Release
正在处理它?好吧,在执行所有任务之前,您不能处理信号量。因此,您需要使用
块等待它们在
内全部完成,或者手动处理。这两种选择都取决于你想怎么做