我必须编写为一个项目创建两个线程的代码。一个线程处理由静态列表访问的信息,该列表由事件处理程序接收,然后线程必须将一些数据发送到串行端口。另一个线程必须等待用户在控制台屏幕上输入数据,然后将数据发送到同一个串行端口。如何创建第二个线程以在后台运行?如何允许该线程向串口发送数据?如何创建锁,以便在事件处理程序将新信息添加到静态列表时后台线程暂停?
问问题
3022 次
1 回答
3
另一种选择是让主线程处理用户输入和后台线程处理信息。这两种格式都格式化需要进入串行端口的数据并将该数据放入队列中。第三个线程从队列中删除数据并将其写入串行端口。
队列是一个BlockingCollection<string>,一种可以处理多个读取器和写入器的并发数据结构。
这样做的好处是您没有显式锁定,因此您消除了一堆潜在的多线程危险。处理线程不会阻塞输出,而只是将数据放入队列并继续。这允许处理以全速进行。
它还可以防止如果用户键入某些内容,然后程序必须等待处理器的消息被发送,然后他的消息被发送,可能会发生延迟。
请注意,BlockingCollection<byte[]>
如果您通过串行端口发送的数据是二进制而不是字符串,则该集合可能是 a。
这会创建一个比您绝对需要的线程更多的线程,但在我看来,这是一种更简洁的设计。
所以你有了:
private BlockingCollection<string> outputQueue = new BlockingCollection<string>();
// the thread that processes information
private void DataProcessor()
{
// initialization
// process data
while ()
{
string foo = CreateOutputFromData();
// put it on the queue
outputQueue.Add(foo);
}
}
// the output thread
private void OutputThread()
{
// initialize serial port
// read data from queue until end
string text;
while (outputQueue.TryTake(out text, Timeout.Infinite))
{
// output text to serial port
}
}
// main thread
public Main()
{
// create the processing thread
var processingThread = Task.Factory.StartNew(() => DataProcessor(), TaskCreationOptions.LongRunning);
// create the output thread
var outputThread = Task.Factory.StartNew(() => OutputThread(), TaskCreationOptions.LongRunning);
// wait for user input and process
while ()
{
var input = Console.ReadLine();
// potentially process input before sending it out
var dataToOutput = ProcessInput(input);
// put it on the queue
outputQueue.Add(dataToOutput);
}
// tell processing thread to exit
// when you're all done, mark the queue as finished
outputQueue.CompleteAdding();
// wait for the threads to exit.
Task.WaitAll(outputThread, processingThread);
}
于 2013-10-31T17:04:28.257 回答