【问题标题】:Stop semphore task execution if exception occurs in current running task如果当前正在运行的任务发生异常,则停止信号任务的执行
【发布时间】:2017-10-13 20:55:40
【问题描述】:

我有以下测试代码来模拟信号量的使用和限制任务的执行。如果其中一个正在运行的任务引发如下异常,有没有办法不继续创建新任务。我不需要现有任务停止运行,我只希望遇到异常后不再启动新任务。

目前任务都将在下面的这个场景中开始。由于抛出异常,我希望它在运行一些任务后停止。

            var testStrings = new List<string>();
            for (var i = 0; i < 5000; i++)
            {
                testStrings.Add($"string-{i}");
            }

            using (var semaphore = new SemaphoreSlim(10))
            {
                var tasks = testStrings.Select(async testString =>
                {
                    await semaphore.WaitAsync();
                    try
                    {
                        Console.WriteLine($"{testString}-Start");
                        await Task.Delay(2000);
                        throw new Exception("test");
                    }
                    finally
                    {
                        semaphore.Release();
                    }
                });

                await Task.WhenAll(tasks);
            }

【问题讨论】:

  • 天真的方法是在错误时设置标志,如果标志被设置,则从任何任务(即使在执行期间)返回。这仍然需要启动所有任务的开销。
  • 我想如果我在尝试中添加一个 catch 块并说 if (!cancellationTokenSource.IsCancellationRequested)cancellationTokenSource.Cancel();然后将每个都包装在一个可能有效的 if (!cancellationToken.IsCancellationRequested) 中

标签: c# task semaphore


【解决方案1】:

根据 Sinatr 的 cmets,我认为通过添加要监控的取消令牌可能对我有用。

       var testStrings = new List<string>();
        for (var i = 0; i < 5000; i++)
        {
            testStrings.Add($"string-{i}");
        }

        var cancellationTokenSource = new CancellationTokenSource();
        var cancellationToken = cancellationTokenSource.Token;

        using (var semaphore = new SemaphoreSlim(10))
        {
            var tasks = testStrings.Select(async testString =>
            {
                    await semaphore.WaitAsync();
                    try
                    {
                       if (!cancellationToken.IsCancellationRequested)
                       {
                           Console.WriteLine($"{testString}-Start");
                           await Task.Delay(2000);
                           throw new Exception("test");
                       }
                    }
                    catch (Exception ex)
                    {
                        if (!cancellationTokenSource.IsCancellationRequested)
                            cancellationTokenSource.Cancel();
                        throw;
                    }
                    finally
                    {
                        semaphore.Release();
                    }
            });

            await Task.WhenAll(tasks);
        }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多