使用任务和阻止集合来永不结束任务

时间:2014-08-25 17:27:05

标签: c# multithreading task blockingcollection

我希望从线上读取数据并将其发送到解析内容的函数。由于消息的大小可能不同(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;
            }
        }       
    }

读取电线(这在一个线程中运行):

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;
           }
      }
}

所以有人能告诉我这里我做错了什么吗?

0 个答案:

没有答案