Мне нужно создать шлюз для ресурса в модели асинхронного программирования, чтобы один и только один поток мог иметь доступ к ресурсу в любой момент времени. Учитывая модель асинхронного программирования, я бы хотел, чтобы оставшиеся запросы к ресурсу были поставлены в очередь, чтобы не блокировать потоки в ожидании доступности ресурса.
Я посмотрел и нашел ворота для чтения / записи в библиотеке потоковых данных Джеффри Рихтера, однако я ищу что-то немного другое.
У меня есть смутное представление о том, что подпись класса gate должна выглядеть следующим образом:
public class Gate
{
public IAsyncResult BeginEnterGate(AsyncCallback callback, object state)
{
...
}
public GateRequest EndEnterGate(IAsyncResult result)
{
return ...;
}
}
Возвращенный запрос шлюза должен быть IDisposable, и при утилизации шлюз позволит следующему потоку использовать ресурс.
public class GateRequest : IDisposable
{
public void Dispose()
{
/* release gate */
}
}
Имея это, я могу использовать библиотеку мощных потоков Джефри Риктерса следующим образом:
public IAsyncResult BeginFoo(string bar, AsyncCallback callback, object state)
{
AsyncEnumerator ae = new AsyncEnumerator();
return ae.BeginExecute(DoFoo(ae, bar), callback, state);
}
public void EndFoo(IAsyncResult result)
{
AsyncEnumerator.FromAsyncResult(result).EndExecute(result);
}
private IEnumerator<int> DoFoo(AsyncEnumerator ae, string bar)
{
gate.BeginEnterGate(ae.End(), null);
yield return 1;
var gateReleaser = gate.EndEnterGate(ae.DequeueAsyncResult());
using (gateReleaser)
{
/* do work related to the resource */
}
}
Возможно, я смотрю слепо на определенный способ решения этой проблемы, поэтому я также открыт для других предложений.