0

我必须编写为一个项目创建两个线程的代码。一个线程处理由静态列表访问的信息,该列表由事件处理程序接收,然后线程必须将一些数据发送到串行端口。另一个线程必须等待用户在控制台屏幕上输入数据,然后将数据发送到同一个串行端口。如何创建第二个线程以在后台运行?如何允许该线程向串口发送数据?如何创建锁,以便在事件处理程序将新信息添加到静态列表时后台线程暂停?

4

1 回答 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 回答