Брокер, который делает асинхронные вызовы с синхронным фасадом в C#

Я хочу сделать много звонков через websocket и получить результат для каждого звонка.

т.е.

_svc.DoAthing(param) =broker calls=> ws.SendMessage(doathingmessage(ticket))
                     <=broker returns= ws.Onmessage+=handler=>(doathingresult(ticket))

Каков наилучший способ сделать брокера таким, чтобы

  1. Этот асинхронный запрос выглядит синхронно
  2. Брокер может обрабатывать сотни запросов
  3. Клиент не должен постоянно опрашивать свой поток, он должен либо блокировать, либо ждать.

Не уверен, является ли наилучшим способом провести несколько потоков, опрашивающих билеты.

1 ответ

Решение

Я думаю, что это будет работать хорошо, но я все еще ищу более элегантное решение

    private ConcurrentDictionary<Guid, ManualResetEvent> _waitingClients = new ConcurrentDictionary<Guid, ManualResetEvent>();
    private ConcurrentDictionary<Guid, byte[]> _hostResponses = new ConcurrentDictionary<Guid, byte[]>();

    public TEventResult SendCommand<TEventResult>(ICommand cmd)
    {
        var mre = new ManualResetEvent(false);
        var s = _serialize(cmd);
        if(_waitingClients.TryAdd(cmd.Ticket, mre))
        {
            if (!_sendDownPipe(s))
            {
                _waitingClients.TryRemove(cmd.Ticket, out mre);
                throw new Exception("Could not get Response");
            }
        }
        mre.WaitOne();//todo timeout

        byte[] resp;
        if(_hostResponses.TryRemove(cmd.Ticket, out resp))
        {
            var o = _deserialize<TEventResult>(resp);
            return o;
        }

        throw new Exception("Could not get response!");
    }
    private void _eventRecieved(byte[] s)
    {
        var evt = _deserialize<IEvent>(s);
        if(_hostResponses.TryAdd(evt.Ticket, s))
        {
            ManualResetEvent mre;
            if(_waitingClients.TryRemove(evt.Ticket, out mre))
            {
                mre.Set();
            }
        }
    }
Другие вопросы по тегам