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