【问题标题】:Can I find out if no threads are waiting for a Semaphore?我可以找出是否没有线程在等待信号量吗?
【发布时间】:2013-08-01 08:44:50
【问题描述】:

我的应用程序处理许多同时下载。我当时只允许运行 3 个下载线程,其他下载正在排队等待信号量。

代码:

private static Semaphore semPool = new Semaphore(3, 3);
private static CancellationTokenSource cts = new CancellationTokenSource();

X 次下载等待运行:

semPool.WaitOne();
DownloadItem d = new DownloadItem(fileInfo, cts.Token, launchAfterDownload);
//wait for download to be complete
semPool.Release()

现在,我想做的是有一种方法可以取消所有下载。我通过将 cts.Token 设置为已取消来做到这一点,但我想在所有当前(和等待的)下载都被取消时重置 cts.Token。

也就是说,我想等到 semPool 有 3 个单位。

public static void CancelAllDownloads()
{
    cts.Cancel();
    //wait until semPool has 3
    cts = new CancellationTokenSource();
}

如果我按照现在的样子调用 CancelAllDownloads(),正在运行的 3 个下载将被取消,但由于取消令牌被重置,正在等待的下载将运行。我也想取消所有等待的,然后重置取消令牌。

【问题讨论】:

  • 您不能使用 IsCanceled 成员或静态成员,如果正在调用 CancelAllDownloads 并且在调用 semPool.WaitOne() 后检查该成员,则该成员设置为 true。您可以通过使用锁定对象来确保它的安全。如果已设置,只需从您的线程返回,因为此时它还没有开始下载任何内容..

标签: c# .net


【解决方案1】:

您可以做的是改用SemaphoreSlim 类。

这个类有你要求的功能,使用它你可以取消所有当前的下载过程,包括运行和等待。然后代码看起来像:

private static SemaphoreSlim semPool = new SemaphoreSlim(3, 3);

semPool.Wait(cts.Token);

public static void CancelAllDownloads()
    {
        cts.Cancel();
        cts = new CancellationTokenSource();
    }

【讨论】:

    猜你喜欢
    • 2019-09-27
    • 1970-01-01
    • 1970-01-01
    • 2016-12-12
    • 1970-01-01
    • 1970-01-01
    • 2020-03-10
    • 1970-01-01
    • 2013-02-07
    相关资源
    最近更新 更多