在WaitAsync时配置SemaphoreSlim

时间:2015-08-16 13:58:58

标签: .net multithreading semaphore dispose idisposable

SemaphoreSlim的文档说,只有在所有其他操作完成后才能使用Dispose。

如何调整以下类,以便线程B可以在线程A等待Async()时调用Dispose()。调用Dispose()时,Async()必须抛出ObjectDisposedException。

class A
{
   SemaphoreSlim _sem = new SemaphoreSlim(0);
   public Task Async() { return _sem.WaitAsync(); }
   public void Dispose() { _sem.Dispose(); }
}

1 个答案:

答案 0 :(得分:0)

  

如何调整以下类,以便线程B可以在线程A等待Async()时调用Dispose()

不应该。正如您引用的文档所述,如果未完成所有操作,则不应调用Dispose()。如果还有一个线程仍在等待WaitAsync(),则该操作未完成,因此不应调用Dispose()

来自评论:

  

调用Dispose作为取消所有待处理请求和释放资源的方法。

这是取消请求的一种不明智的方式。

当然,如果你做了让对象进入无效状态的事情,那么可能导致其他线程中的异常,可能导致他们中止并因此放弃他们的工作。

但是不能保证他们应该这样做,而且他们也很有可能被编码,以便在这样的时间点不会出现这样的例外情况并进行适当的清理。

如果您想取消,请进行正常取消。因此创建任务:

public Task Async(CancellationToken cancellationToken)
{
  return _sem.WaitAsync(cancellationToken);
}

并使用cancellationToken取消。