Создание неблокирующего асинхронного гейта в C # - PullRequest
2 голосов
/ 09 января 2011

Мне нужно создать шлюз для ресурса в модели асинхронного программирования, чтобы один и только один поток мог иметь доступ к ресурсу в любой момент времени. Учитывая модель асинхронного программирования, я бы хотел, чтобы оставшиеся запросы к ресурсу были поставлены в очередь, чтобы не блокировать потоки в ожидании доступности ресурса.

Я посмотрел и нашел ворота для чтения / записи в библиотеке потоковых данных Джеффри Рихтера, однако я ищу что-то немного другое.

У меня есть смутное представление о том, что подпись класса 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 */
  }
}

Возможно, я смотрю слепо на определенный способ решения этой проблемы, поэтому я также открыт для других предложений.

1 Ответ

3 голосов
/ 10 января 2011

My Power Threading Library имеет класс SyncGate, который интегрируется с AsyncEnumerator. Я думаю, что это обеспечивает API, который вы хотите.

...