/// <summary> /// Send data (byte[][]) to the remote host. Then wait for a reply from the server. /// </summary> /// <param name="client"></param> /// <param name="data">data to send to server</param> /// <param name="timeout">maximum time to wait for a reply, if time expired: return null</param> /// <returns>received data or null</returns> public static async Task <Message> SendAndGetReplyAsync(this EasyTcpClient client, TimeSpan?timeout = null, params byte[][] data) { Message reply = null; using var signal = new SemaphoreSlim(0, 1); // Use SemaphoreSlim as async ManualResetEventSlim client.DataReceiveHandler = message => { reply = message; client.ResetDataReceiveHandler(); // Function is no longer used when signal is disposed, therefore ignore this warning // ReSharper disable once AccessToDisposedClosure signal.Release(); }; client.Send(data); await signal.WaitAsync(timeout ?? TimeSpan.FromMilliseconds(DefaultTimeout)); if (reply == null) { client.ResetDataReceiveHandler(); } return(reply); }
/// <summary> /// Send data to remote host. Then wait and return the reply /// </summary> /// <param name="client"></param> /// <param name="data">data to send to remote host</param> /// <param name="timeout">maximum time to wait for a reply, return null when time expires</param> /// <returns>received reply</returns> public static Message SendAndGetReply(this EasyTcpClient client, TimeSpan?timeout = null, params byte[][] data) { Message reply = null; using var signal = new ManualResetEventSlim(); client.DataReceiveHandler = message => { reply = message; client.ResetDataReceiveHandler(); signal.Set(); // Function is no longer used when signal is disposed, therefore this is completely safe return(Task.CompletedTask); }; client.Send(data); signal.Wait(timeout ?? TimeSpan.FromMilliseconds(DefaultTimeout)); if (reply == null) { client.ResetDataReceiveHandler(); } return(reply); }