![](/img/trans.png)
[英]How does HttpContext.Current work in a multi-threaded environment?
[英]How to protect resources that may be used in a multi-threaded or async environment?
我正在開發一個供各種消費者使用的 C# API。 此 API 提供對共享資源(在我的情況下是進行串行通信的硬件)的訪問,通常會有幾個不同的參與者嘗試同時使用它。
我的問題是我的一些消費者希望在多線程環境中使用它 - 每個參與者獨立工作並嘗試使用資源。 一個簡單的鎖在這里工作正常。 但是我的一些消費者更喜歡使用 async-await 和時間切片資源。 (據我所知)這需要一個異步鎖來將時間片交還給其他任務; 在鎖上阻塞會停止整個線程。
而且我認為擁有串行鎖充其量是性能不佳的,最糟糕的是潛在的競爭條件或死鎖。
那么,對於潛在的並發使用,我如何才能在一個公共代碼庫中保護這個共享資源呢?
您可以使用SemaphoreSlim
,請求數為 1。 SemaphoreSlim
允許使用WaitAsync
和舊的同步方式以async
方式鎖定:
await _semphore.WaitAsync()
try
{
... use shared resource.
}
finally
{
_semphore.Release()
}
您還可以根據 Stephen Toub 的精彩AsyncLock
構建異步協調原語,第 6 部分:AsyncLock編寫自己的AsyncLock 。 我在我的應用程序中做到了,並允許在同一構造上同時使用同步和異步鎖。
用法:
// Async
using (await _asyncLock.LockAsync())
{
... use shared resource.
}
// Synchronous
using (_asyncLock.Lock())
{
... use shared resource.
}
執行:
class AsyncLock
{
private readonly Task<IDisposable> _releaserTask;
private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1);
private readonly IDisposable _releaser;
public AsyncLock()
{
_releaser = new Releaser(_semaphore);
_releaserTask = Task.FromResult(_releaser);
}
public IDisposable Lock()
{
_semaphore.Wait();
return _releaser;
}
public Task<IDisposable> LockAsync()
{
var waitTask = _semaphore.WaitAsync();
return waitTask.IsCompleted
? _releaserTask
: waitTask.ContinueWith(
(_, releaser) => (IDisposable) releaser,
_releaser,
CancellationToken.None,
TaskContinuationOptions.ExecuteSynchronously,
TaskScheduler.Default);
}
private class Releaser : IDisposable
{
private readonly SemaphoreSlim _semaphore;
public Releaser(SemaphoreSlim semaphore)
{
_semaphore = semaphore;
}
public void Dispose()
{
_semaphore.Release();
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.