private async Task CommandStreamLoop(CommandHanderStreamContext ctx) { lock (_streams) _streams.Add(ctx.StreamId, ctx); ctx.InitEvent.Set(); try { while (!_disposed) { int commandId; int tag; int size; Command command; (command, commandId, tag, size) = await ctx.Stream.ReadCommand().ConfigureAwait(false); if (command == null) { Log.InfoFormat($"End of stream {ctx.StreamId}"); return; } _stats.StatReceive(size); if (tag == 0) { var handle = GetHandlerMethod(command.GetType()); ThreadPool.QueueUserWorkItem((_) => handle.Invoke(this, new object[] { command, ctx.Stream, commandId, ctx.Stream.Id })); } else { var uId = CommandStream.GetCommandId(ctx.StreamId, tag); lock (_unansweredRequests) { RequestBase req; if (!_unansweredRequests.TryGetValue(uId, out req)) { Log.Warn($"No unanswered requests with tag {tag}. Uniq command id: {uId}"); } else { req.SetResult(command, ctx.StreamId); _unansweredRequests.TryRemove(uId, out var t); } } } } } catch (Exception e) { Console.WriteLine(e); } finally { ctx.Stream.Close(); lock (_streams) _streams.Remove(ctx.StreamId); OnClose(ctx.StreamId); } }
public int AddSource(TcpClient client) { var streamId = Interlocked.Increment(ref _streamCount); var s = new CommandStream(streamId, client, _serializer); var ctx = new CommandHanderStreamContext { StreamId = streamId, Stream = s, InitEvent = new ManualResetEventSlim(false) }; var t = CommandStreamLoop(ctx); _tasks.Add(t); ctx.InitEvent.Wait(); return(streamId); }