C# 将任务和blockingcollections用于从不重复的任务

C# 将任务和blockingcollections用于从不重复的任务,c#,multithreading,task,blockingcollection,C#,Multithreading,Task,Blockingcollection,我希望从线路上读取数据,并将其发送到函数以解析内容。由于消息(xml)的大小可能不同,因此我可以读取整个消息、多条消息或消息的一部分 我试图使用BlockingCollection实现代码,当我从线路上读取数据时,我会调用TryAdd,并使用使用者线程从BlockingCollection中提取数据进行解析。这些例子看起来很直截了当,但它们似乎只起作用一次,然后退出。我希望消费者在收到消息时不断解析。请参阅下面的代码了解我当前正在做的事情 处理信息: private static Blo

我希望从线路上读取数据,并将其发送到函数以解析内容。由于消息(xml)的大小可能不同,因此我可以读取整个消息、多条消息或消息的一部分

我试图使用
BlockingCollection
实现代码,当我从线路上读取数据时,我会调用
TryAdd
,并使用使用者线程从
BlockingCollection
中提取数据进行解析。这些例子看起来很直截了当,但它们似乎只起作用一次,然后退出。我希望消费者在收到消息时不断解析。请参阅下面的代码了解我当前正在做的事情

处理信息:

    private static BlockingCollection<byte[]> queue = new BlockingCollection<byte[]>();

    public XmlHandler()
    {
        CancellationTokenSource cts = new CancellationTokenSource();
        Task.Factory.StartNew(() =>
      {
          if (Console.ReadKey().KeyChar == 'c')
              cts.Cancel();
      });


        Task.Factory.StartNew(() => ParserWorker(queue, cts.Token));

    }
    //run producer
    public void AddData(byte[] data, int bytesRead)
    {
        bool success = false;
        try
        {
            success = queue.TryAdd(data);
        }
        catch (OperationCanceledException)
        {
            Console.WriteLine("Add loop canceled.");
            queue.CompleteAdding();
        }

        if (success)
        {
            Console.WriteLine(" Add:{0}", data);
        }
        else
        {
            Console.Write(" AddBlocked");
        }

        System.Console.WriteLine("queue count = " + queue.Count);
    }

    private static void ParserWorker(BlockingCollection<byte[]> bc, CancellationToken ct)
    {
        ASCIIEncoding encoder = new ASCIIEncoding();
        String xmlString;

        while (!bc.IsCompleted)
        {
            byte[] nextItem;
            try
            {

                if (!bc.TryTake(out nextItem, 0, ct))
                {
                    Console.WriteLine(" Take Blocked");
                }
                else
                {
                    xmlString = encoder.GetString(nextItem, 0, nextItem.Length);
                    System.Console.WriteLine(xmlString);
                }

            }

            catch (OperationCanceledException)
            {
                Console.WriteLine("Taking canceled.");
                break;
            }
        }       
    }

有人能告诉我我做错了什么吗

“工作一次,然后退出”是什么意思?程序是退出还是while循环?在我的例子中,它将xml字符串写入1次,然后我无法向队列添加更多数据。如果我没有启动ParserWorker,那么代码将继续添加到队列中。我不知道代码是在Parserworker中被阻塞,还是在bc.iscompleted变为true且任务退出后被阻塞。您是否可以添加执行
XmlHandler
?编辑并处理流外消息的代码。流是否继续读取?还是在第一次读取后等待更多输入时被阻止?
private void HandleClientComm(object client)
{
      TcpClient tcpClient = (TcpClient)client;
      NetworkStream clientStream = tcpClient.GetStream();

      byte[] message = new byte[8192];
      int bytesRead;

      while (true)
      {
          bytesRead = 0;

          try
          {

              bytesRead = clientStream.Read(message, 0, 4096);
              byte[] temp = new byte[bytesRead];
              Array.Copy(message, temp, bytesRead);

              /*CODE WILL HANG HERE...*/
              ASCIIEncoding encoder = new ASCIIEncoding();
              String xmlString = encoder.GetString(message, 0, message.Length);
              System.Console.WriteLine(xmlString);
              /*DOES NOT GO BEYOND LINE ABOVE */

              handler.AddData(message, bytesRead);  //xmlhandler
           }
           catch (Exception e)
           {
               System.Console.WriteLine(e.ToString());
               break;
           }

           if (bytesRead == 0)
           {
               break;
           }
      }
}