private async Task <Responses.IVPNResponse> SendRecvAsync(Requests.Request request, TimeSpan timeout) { // initialize waiter Responses.IVPNResponse response = null; var evt = new ManualResetEvent(false); Action <Responses.IVPNResponse> waiter = new Action <Responses.IVPNResponse>((resp) => { if (resp.Idx == request.Idx) { if (response != null) { return; } response = resp; evt.Set(); } }); try { // register waiter lock (__ResponseWaiters) { __RequestCounter += 1; if (__RequestCounter == 0) { __RequestCounter = 1; } request.Idx = __RequestCounter; __ResponseWaiters.Add(waiter); } // send request SendRequest(request); // wait for response await Task.Run(() => { if (WaitHandle.WaitTimeout == WaitHandle.WaitAny(new WaitHandle[] { evt, __CancellationToken.Token.WaitHandle }, timeout)) { throw new TimeoutException("Response timeout"); } }); } finally { // un-register waiter lock (__ResponseWaiters) { __ResponseWaiters.Remove(waiter); } } return(response); }
private void responseReceived(Responses.IVPNResponse response) { lock (__ResponseWaiters) { foreach (var waiter in __ResponseWaiters) { waiter(response); } } }