我想使用锁或类似的同步来保护关键部分。同时我想听一个CancellationToken。
现在我正在使用这样的互斥锁,但互斥锁没有那么好的性能。我可以使用任何其他同步类(包括新的 .Net 4.0)来代替互斥锁吗?
WaitHandle.WaitAny(new[] { CancelToken.WaitHandle, _mutex});
CancelToken.ThrowIfCancellationRequested();
我想使用锁或类似的同步来保护关键部分。同时我想听一个CancellationToken。
现在我正在使用这样的互斥锁,但互斥锁没有那么好的性能。我可以使用任何其他同步类(包括新的 .Net 4.0)来代替互斥锁吗?
WaitHandle.WaitAny(new[] { CancelToken.WaitHandle, _mutex});
CancelToken.ThrowIfCancellationRequested();
看看新.NET 4.0 Framework
功能SemaphoreSlim Class。它提供SemaphoreSlim.Wait(CancellationToken)方法。
阻塞当前线程,直到它可以进入 SemaphoreSlim,同时观察一个 CancellationToken
从某种角度来看,在这种简单的情况下使用 Semaphore 可能是一种开销,因为最初它旨在为多个线程提供访问,但也许您会发现它很有用。
编辑:代码片段
CancellationToken token = new CancellationToken();
SemaphoreSlim semaphore = new SemaphoreSlim(1,1);
bool tokenCanceled = false;
try {
try {
// block section entrance for other threads
semaphore.Wait(token);
}
catch (OperationCanceledException) {
// The token was canceled and the semaphore was NOT entered...
tokenCanceled = true;
}
// critical section code
// ...
if (token.IsCancellationRequested)
{
// ...
}
}
finally {
if (!tokenCanceled)
semaphore.Release();
}
private object _lockObject = new object();
lock (_lockObject)
{
// critical section
using (token.Register(() => token.ThrowIfCancellationRequested())
{
// Do something that might need cancelling.
}
}
调用Cancel()
令牌将导致ThrowIfCancellationRequested()
被调用,因为这是与Register
回调挂钩的内容。您可以在此处放置您想要的任何取消逻辑。这种方法很棒,因为您可以通过强制导致调用完成的条件来取消阻塞调用。
ThrowIfCancellationRequested 引发 OperationCanceledException。您需要在调用线程上处理此问题,否则您的整个过程可能会被关闭。一种简单的方法是使用 Task 类启动您的任务,该类将聚合所有异常以供您在调用线程上处理。
try
{
var t = new Task(() => LongRunningMethod());
t.Start();
t.Wait();
}
catch (AggregateException ex)
{
ex.Handle(x => true); // this effectively swallows any exceptions
}
这里有一些好东西,包括合作取消